IOS提供了日期选择器UIDatePicker,它可以实现对日期的选择。日期选择器有4种模式:日期、日期和时间、时间和倒计时定时器。日期选择器使用比较简单,这里我们就不去实现它了。
有的时候我们可能需要输入除了日期之外的其他内容,比如籍贯等。IOS为我们提供了UIPickerView,它是UIDatePicker的父类。UIPickerView是非常灵活的,它的滚轮可以设定,每一个滚轮的内容也可以设定。与UIDatePicker不同的是,UIPickerView需要两个非常重要的协议——UIPickerViewDelegate和UIPickerViewDataSource。
这里我们简单实现一个省和市联动的选择器。有两个滚轮,一个选择省,一个选择市。选择省,列出相应的市;选定后把联动结果用label显示出来。
在实现之前我们需要建立数据,我们用plist文件保存数据:
需求比较简单,直接贴代码(基于storyboard和ARC)。
ViewController.h相关代码:
#import <UIKit/UIKit.h> @interface ViewController : UIViewController<UIPickerViewDataSource,UIPickerViewDelegate> @property (weak, nonatomic) IBOutlet UILabel *selectedLabel; @property (weak, nonatomic) IBOutlet UIPickerView *pickerView; @property (strong,nonatomic) NSDictionary *pickerData; @property (strong,nonatomic) NSArray *pickerProvincesData; @property (strong,nonatomic) NSArray *pickerCitiesData; @end
ViewController.m相关代码:
#import "ViewController.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; self.pickerView.delegate=self; self.pickerView.dataSource=self; //获取所有数据 NSString *dataPath=[[NSBundle mainBundle] pathForResource:@"provinces_cities" ofType:@"plist"]; self.pickerData=[NSDictionary dictionaryWithContentsOfFile:dataPath]; //省数据 self.pickerProvincesData=[self.pickerData allKeys]; //默认显示第一个省得市 self.pickerCitiesData=[self.pickerData objectForKey:[self.pickerProvincesData objectAtIndex:0]]; [self showSelected]; } //UIPickerViewDataSource //选择器中拨轮的数目 -(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView { return 2; } //UIPickerViewDataSource //选择器中某个拨轮的行数 -(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component { if(component==0){//省 return [self.pickerProvincesData count]; }else{//市 return [self.pickerCitiesData count]; } } //UIPickerViewDelegate //选中选择器中某个拨轮的某行时触发 -(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component { if(component==0){//选中省时显示对应的市 NSString *province=[self.pickerProvincesData objectAtIndex:row]; NSArray *cities=[self.pickerData objectForKey:province]; self.pickerCitiesData=cities; //重新加载市的数据 [self.pickerView reloadComponent:1]; } [self showSelected]; } //UIPickerViewDelegate //选择器中某个拨轮的某行显示的数据 -(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component { if(component==0){ return [self.pickerProvincesData objectAtIndex:row]; }else{ return [self.pickerCitiesData objectAtIndex:row]; } } -(void)showSelected { NSInteger provinceRow=[self.pickerView selectedRowInComponent:0]; NSInteger cityRow=[self.pickerView selectedRowInComponent:1]; NSString *str=[NSString stringWithFormat:@"%@:%@",[self.pickerProvincesData objectAtIndex:provinceRow],[self.pickerCitiesData objectAtIndex:cityRow]]; self.selectedLabel.text=str; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end
与UITextField等简单控件不同的是,UIPickerView除了委托协议外,还有数据源协议。数据源和委托的角色不同:委托对象负责控制控件外观,如选择器的宽度、选择器的行高等信息,此外,还负责对控件的事件和状态变化做出反应。数据源对象是控件与应用数据的桥梁,如选择器的行数、滚轮数等信息。
数据源协议中(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView和
(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component方法是必须要实现的。
代理协议中我们通常只需要实现下面两个常用的方法即可,
(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component;
(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component