1

I have a UIPickerView that is being "pushed" to UINavigationController like this:

 [self.navigationController pushViewController:vc animated:YES];

I would like to set the selected row.

I added in ViewDidAppear:

for (int i = 0; i < [countryCodes count]; i++)
    {
        if ([[countryCodes objectAtIndex:i] isEqualToString:selectedCountryCode]){
            [_countryPicker selectRow:i inComponent:0 animated:YES];
            countrySelectedRow = i;
            break;
        }

    }
    [_countryPicker reloadAllComponents];

where i is dynamic (being changed based on data that is changing in that view controller)

It works only if I restart the app.

If I go back and forth in the navigation it doesn't work

How can I make the UIPickerView choose the the correct row?

I can see in debug mode that the lines in viewDidAppear are called. Maybe the component is being created and I can't change it?

This is how I create the UIPickerView:

- (void)viewDidLoad
{
_countryPicker = [[UIPickerView alloc] init];
    [self initPicker:_countryPicker textField:_countryText];
}

- (void)initPicker:(UIPickerView*)pickerView textField:(UITextField*) textField
{
    CGRect pickerFrame = CGRectMake(0, 0, 200, 216);
    pickerView.frame = pickerFrame;
    pickerView.userInteractionEnabled = YES;
    pickerView.dataSource = self;
    pickerView.hidden = YES;
    pickerView.delegate = self;
    pickerView.showsSelectionIndicator = YES;
    [self.view addSubview:pickerView];
    [textField setInputView:pickerView];

    textField.delegate = self;
    [pickerView removeFromSuperview];

}
Anindya Sengupta
  • 2,539
  • 2
  • 21
  • 27
Dejell
  • 13,947
  • 40
  • 146
  • 229
  • Can you show the code where `i` is being set – Flexicoder Mar 11 '14 at 16:41
  • And did you set a breakpoint to see if the isEqual ever happens? – mackworth Mar 11 '14 at 16:45
  • Yes. of course. It happens – Dejell Mar 11 '14 at 16:46
  • Sorry for "obvious" questions, but I have almost exactly the same code in my app, and it works fine for me. – mackworth Mar 11 '14 at 16:51
  • How do you create the picker make sure you assign the delegate – meda Mar 11 '14 at 16:54
  • And _countryPicker isn't nil the second time through? – mackworth Mar 11 '14 at 16:56
  • I updated my code. I have more than one picker view and this is why I create it like this – Dejell Mar 11 '14 at 16:58
  • @mackworth no it's notnil – Dejell Mar 11 '14 at 17:00
  • 4
    Just curious: why add to self.view and then remove? – mackworth Mar 11 '14 at 17:13
  • @mackworth redundant code. I removed it – Dejell Mar 11 '14 at 17:28
  • 2
    Built a simulation using all your code as shown with no problem going into a subVC and back, going to parent and back (which recreates picker) and it all works fine setting picker to a row. (BTW, your first sentence is incorrect, no?, you're not pushing the pickerview, you're pushing a viewcontroller containing a textview that has the pickview as its input view.) Have you surrounded the setComponent with `NSLog(@"picker was(is): %d",[_countryPicker selectedRowInComponent:0]);` to be absolutely certain it's setting/retrieving the selectedRow – mackworth Mar 11 '14 at 18:51
  • I tried your code and works for me (same as mackworth). Can you add the code which you add UIPickerView in the nav controller? – Dimitris Bouzikas Mar 16 '14 at 22:57
  • selectedCountryCode variable. What is the scope? Is it a global variable? – Anindya Sengupta Mar 18 '14 at 15:45
  • make sure your selectedCountryCode has the expected value each time you navigate to the View Controller, by using NSLog. – Jibran K Mar 20 '14 at 09:32
  • Try this link i gave a code for UIPicker http://stackoverflow.com/questions/20883388/display-done-button-on-uipickerview/20883575#20883575 – Charan Giri Mar 20 '14 at 13:18

3 Answers3

1

After you set the selected row you then call this...

[_countryPicker reloadAllComponents];

Thats going to wipe out your selection? I would remove that line

Flexicoder
  • 8,251
  • 4
  • 42
  • 56
1

If you make the selectedCountryCode variable part of a singleton class (for example AppDelegate or preferebly some other), and then equate the value, this is surely going to work. Here I don't understand how the selectedCountryCode is expected to be retained even after the view is popped.

I tried with making the string a part of AppDelegate (which is of course not a good practice. One should put it in another singleton class).

#import "CViewController.h"
#import "AppDelegate.h"


@interface CViewController ()<UITextFieldDelegate, UIPickerViewDelegate, UIPickerViewDataSource>

@property(nonatomic, strong) UIPickerView *countryPicker;
@property (nonatomic, weak) IBOutlet UITextField *countryText;
@property (nonatomic, strong) NSArray *countryCodes;
@property (nonatomic, assign) int countrySelectedRow;
@property (nonatomic,strong) AppDelegate *delegate;

@end

@implementation CViewController


- (void)viewDidLoad
{
    self.delegate = [[UIApplication sharedApplication] delegate];
    _countryPicker = [[UIPickerView alloc] init];
    [self initPicker:_countryPicker textField:_countryText];
    self.countryCodes = @[@"A", @"B", @"C", @"D", @"E"];
}

- (void)initPicker:(UIPickerView*)pickerView textField:(UITextField*) textField
{
    CGRect pickerFrame = CGRectMake(0, 0, 200, 216);
    pickerView.frame = pickerFrame;
    pickerView.userInteractionEnabled = YES;
    pickerView.dataSource = self;
    pickerView.hidden = YES;
    pickerView.delegate = self;
    pickerView.showsSelectionIndicator = YES;
    [self.view addSubview:pickerView];
    [textField setInputView:pickerView];

    textField.delegate = self;

    [pickerView removeFromSuperview];
}

- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
    return [self.countryCodes objectAtIndex:row];
}

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

// returns the # of rows in each component..
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
    return [self.countryCodes count];
}

- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{

    self.delegate.selectedCountryCode = [self.countryCodes objectAtIndex:row];
    NSLog(@"picker was(is): %d",[_countryPicker selectedRowInComponent:0]);
}


-(void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    for (int i = 0; i < [self.countryCodes count]; i++)
    {
        if ([[self.countryCodes objectAtIndex:i] isEqualToString:self.delegate.selectedCountryCode]){
            [_countryPicker selectRow:i inComponent:0 animated:YES];
            self.countrySelectedRow = i;
            break;
        }

    }
    [_countryPicker reloadAllComponents];
}

-(void)textFieldDidBeginEditing:(UITextField *)textField
{
    self.countryPicker.hidden = NO;
}
Anindya Sengupta
  • 2,539
  • 2
  • 21
  • 27
  • Hi, I see in NSLog that the selected country code is set to the right one that the user selected, but in the uipickerview the row is not being selected although the code is being called – Dejell Mar 22 '14 at 17:40
1

You wrote: "where i is dynamic (being changed based on data that is changing in that view controller)"" In your code i is a local variable. Did you mean selectedCountryCode here?

for (int i = 0; i < [countryCodes count]; i++)
{
    if ([[countryCodes objectAtIndex:i] isEqualToString:selectedCountryCode]){
        [_countryPicker selectRow:i inComponent:0 animated:YES];
        countrySelectedRow = i;
        break;
    }
}
[_countryPicker reloadAllComponents];

I am pretty sure selectedCountryCode is not updated correctly. Add NSLog(selectedCountryCode); to check it.

UPDATE:

It seems that problem is somewhere inside a code you did not post in the question. To check your code I created and share a project. Please find it here https://github.com/Avtolic/SOHelper If you will check it you will find that everything works ok.

Avt
  • 16,927
  • 4
  • 52
  • 72
  • I have created a project https://github.com/Avtolic/SOHelper to check where the problem could be. In my project everything works. Maybe it will help you to find your problem. – Avt Mar 22 '14 at 23:11