UIPickerView can't autoselect last row when co

2020-02-10 03:12发布

问题:

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.

回答1:

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.



回答2:

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.