Question

I am trying to save the selection in a UIPickerView as a string, but I seem to be losing the value after I dismiss the view. How can I retain this value?

.m file

/*********************************/
#pragma mark -
#pragma mark PickerView DataSource
//Below are the functions for the UIPicker:

- (NSInteger)numberOfComponentsInPickerView:
(UIPickerView *)pickerView
{
    return 1;
}

//count of categories array denotes how many elements the picker will have
- (NSInteger)pickerView:(UIPickerView *)pickerView
numberOfRowsInComponent:(NSInteger)component
{
    return arrCategorySelection.count;
}

//return the corresponding caregory
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
    return arrCategorySelection[row];
}

/*********************************/
#pragma mark -
#pragma mark PickerView Delegate

//Delegate method for the category picker
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
    //trying to save the value as a string
    selectedCategory = [arrCategorySelection objectAtIndex:row];
}

.h

@property (nonatomic, retain) NSString *selectedCategory;
Was it helpful?

Solution

A property is tied directly to the controller that it is declared in. To use the property, you need to access it before the controller is dismissed, normally with a delegate call. Apple has lots of example code on how to do this. Below is a summary.

Let's say MasterView is presenting PickerView. Normally, you want to do this with a segue.

[self performSegueWithIdentifier:@"Present PickerView" sender:nil];

In PickerView.h you declare a protocol before the @interface portion:

@protocol PickerViewDelegate <NSObject>
    -(void)itemSelected:(NSString*)item;
@end

Then in the @interface portion, you declare a delegate property

@property(weak)id<PickerViewDelegate> delegate;

In MasterView, you need to populate this delegate in your prepareForSegue method

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if ([segue.identifier isEqualToString:@"Present PickerView"]) {
        PickerView *controller = segue.destinationViewController;
        controller.delegate = self;
    }
}

You also need to implement the delegate method (remember, it is best practice for the MasterView to both present and dismiss PickerView)

-(void)itemSelected:(NSString*)item {
    // do something with item
    [self dismissViewControllerAnimated:YES completion:nil];
    // depending on the presentation, you may need this instead
    // [self.navigationController popViewControllerAnimated:YES];
}

Now in PickerView.m, establish some way for the user to say he is done with his selection, say a tap of the save button on the upper right that calls this method:

-(IBAction)saveButtonTapped:(id)sender {
    if (self.delegate && [self.delegate respondsToSelector:@selector(itemSelected:)]) {
        [self.delegate itemSelected:self.selectedCategory];
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top