I have been beating my head against the wall trying to diagnose my app's inability to automatically preselect the last row of a UIPickerView using code that successfully worked under older versions of XCode. I think this is a bug in Xcode rather than iOS 6 because my old app running on an iOS 6 device works properly, but recompiling the code under Xcode 4.5.2 does not behave properly. I have put together the following sample to demonstrate the problem, but before I submit a bug report, I would like opinions from others on this forum to determine if the problem is with my code or is indeed a bug in Xcode/iOS.
I created a single view app and setup the storyboard with a navigation controller, and two IBOutlets, one to a UILabel where I display the selected row, and one to a UIPickerView.
Here is the header file for my custom view controller:
#import <UIKit/UIKit.h>
@interface DisposableViewController : UIViewController
<UIPickerViewDataSource, UIPickerViewDelegate>
@end
Here is the implementation file for my custom view controller:
#import "DisposableViewController.h"
const NSInteger MAX_VALUE = 10;
@interface DisposableViewController ()
@property (weak, nonatomic) IBOutlet UIPickerView *pickerView;
@property (weak, nonatomic) IBOutlet UILabel *selectedValueLabel;
@end
@implementation DisposableViewController
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)viewWillAppear:(BOOL)animated
{
[self.pickerView reloadAllComponents];
[self.pickerView selectRow:MAX_VALUE inComponent:0 animated:NO];
self.selectedValueLabel.text = [NSString stringWithFormat:@"%d", [self.pickerView selectedRowInComponent:0]];
}
//**
//** UIPickerViewDataSource methods
//**
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return MAX_VALUE + 1;
}
//**
//** UIPickerViewDelegate methods
//**
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
return [NSString stringWithFormat:@"%d", row];
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
self.selectedValueLabel.text = [NSString stringWithFormat:@"%d", row];
}
@end
Here is a screenshot demonstrating the problem:
Note that my code tries to autoselect the last row in the UIPickerView in the viewWillAppear: method, but when the program runs, the value label gets the row as 10 when calling [self.pickerView selectedRowInComponent:0], but the UIPickerView itself visually appears to have selected 9. I believe this is a bug, but would like other opinions or suggestions for how I can resolve this problem. Thanks for your attention.
This bug is caused by the Use Autolayout option in the storyboard, but I have found a workaround that allows me to continue using auto layout:
If I call the [pickerView selectRow:inComponent:] method in the viewDidAppear: of my view controller instead of in the viewWillAppear:, then the UIPickerView correctly adjusts to select the correct row though the selection is momentarily visible as the picker rotates from the wrong selection to the correct one.
Definitely looks like a bug relating to the new auto-layout feature in iOS 6. I was experiencing the same thing, but when trying to see if it happened in iOS 5.1, I noticed that it started working.
Try this: in the storyboard or nib file in question, turn off auto-layout.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With