UIPickerView的功能是让用户从一系列待选的值中选取一个他们取需要的值,iPhone闹钟的计时器就使用了UIPickerView来选择时间。
UIPickerView的用法很简单,即初始化->选择数据源->选择委托对象->显示。
IOS使用MVC模式构建App,将视图与模型分开,通过控制器来沟通。UIPickerView就是MVC中的View,要展示的数据属于Model,而数据源就是Control了。UIPickerView的数据源必须遵守一个协议:UIPickerViewDataSource,并且实现其中的两个方法:
// returns the number of 'columns' to display.
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView;
// returns the # of rows in each component..
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component;
一个UIPickerView可以有多个组件(Component),每个组件提供了一列值让用户选择,例如计时器中有小时和分钟两个组件。上面的两个方法确定了UIPickerView中的组件个数以及每个组件中的行数,即一个组件中待选择的值的个数,但是每一行具体代表什么值并没有确定,此时每一行都显示‘?’。这时我们需要再提供一个委托对象给UIPickerView,一个委托对象在MVC中也属于Control,它要遵守UIPickerViewDelegate协议,并且实现协议中的一个方法:
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component;
这个方法可以返回某个UIPickerView中的某个组件的某一行显示的字符串。
UIPickerView中有一个属性showsSelectionIndicator,用来突出当前选择的行,ios7中即在中间增加两条横线来确定当前选定的行,以前的版本是增加一个选定框,官房文档中这个属性的默认值是NO,可以直接将它赋值成YES或者调用SetShowsSelectionIndicator:方法。但是我修改这个属性时发现并没有什么变化,网上查了官方文档,原来ios7中这个属性已经无效了。如果想去掉这两条线,可以调用
如果想要知道用户当前选择了某个组件的哪一行,可以调用方法:selectedRowInComponent:,该方法返回当前行的下标。如果想要动态更新组件显示的数据,可以让需要更新的组件调用reload它的数据或者让所有组件reload它们的数据,这时需要调用以下两个方法:
[[self.pickerView.subviews objectAtIndex:1] setHidden:TRUE];
[[self.pickerView.subviews objectAtIndex:2] setHidden:TRUE];
因为UIPickerView的subview有三层,下标为0的一层显示Component,下标为1和2的两层显示两条横线,但是最好不要这样做。
// Reloading whole view or single component
- (void)reloadAllComponents;
- (void)reloadComponent:(NSInteger)component;
下面贴上我的代码:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.pickerView = [[UIPickerView alloc]init];
self.pickerView.center = self.view.center;
self.pickerView.dataSource = self;
self.pickerView.delegate = self;
[self.view addSubview:self.pickerView];
}
// returns the number of 'columns' to display.
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView;
{
if ([pickerView isEqual:self.pickerView]) {
return 2;
}
return 0;
}
// returns the # of rows in each component..
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component;
{
if ([pickerView isEqual:self.pickerView]) {
if (component == 0) {
return 12;
}else{
return 30;
}
}
return 0;
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component;
{
if ([pickerView isEqual:self.pickerView]) {
if (component == 0) {
return [NSString stringWithFormat:@"Mon %ld",row+1];
}else{
return [NSString stringWithFormat:@"Day %ld",row+1];
}
}
return nil;
}