UIPickerView在iOS开发中是一个很常见的控件,例如计时器选择时间,填写省市区位置时都可以用的上,最近写项目时使用到了这个技术,总结一下。
UIPickerView类似于UITableView这类控件,是需要遵循数据源和代理两个协议的。
我们在使用前添加这两个协议。
@interface ViewController : UIViewController<
UIPickerViewDelegate,
UIPickerViewDataSource
>
@property (nonatomic, strong) UIPickerView* pickerView;
UIPickerViewDataSource
:
此协议中有两个必须实现的方法
分别是设置选择器的行和列数
// 列数
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 3;
}
//行数
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
return 10;
}
// 还有一个比较重要的方法:
// 设置选择的响应事件
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
UIPickerViewDeleagate
:
有以下方法
返回UIPickerView中Component列的宽度
- (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component;
返回UIPickerView中Component列中每行的高度
- (CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component;
当选择某一项Component列中的row行时的回调函数
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
- 标准的UIPickerView内容,只有字符串
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component;
自定义的UIPickerView内容,给每个列,行设置一个UIView对象
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view;
----这里列为component,行row返回一个UIView用来显示在UIPickerView中。reusingView:(UIView *)
刷新数据的方法:
- (void)reloadAllComponents;
- (void)reloadComponent:(NSInteger)component;
大概使用的方法如上所示,下面就开始创建UIPickerView;
_pickerView = [[UIPickerView alloc] init];
_pickerView.delegate = self;
_pickerView.dataSource = self;
_pickerView.frame = CGRectMake(0, HEIGHT * 0.7, WIDTH, HEIGHT * 0.3);
[self.view addSubview:_pickerView];
然后实现必须的方法以及你需要的方法:
这里简单的使用了NSSting显示这种方式
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 3;
}
//
// 行数
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
return 10;
}
代理方法
//
// // 显示内容两种方式NSString,UIView;
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
return @"差不多先生";
}
就实现了下面的效果
这就是一个简单的选择器的使用,但比较单一无法解决实际开发的需求,下面实现了一个省市区绑定选择的UIPickerView。
Demo需求展示如下:
由于这里省市区的数据很多,所以我们利用plist文件来保存信息,这里有一个重构好的文件,链接: plist 密码: 8b9u。
有了文件后,我们首先创建三个数组来保存文件中存的信息,可以提前看一下plist里面存储的数据了解一下类型。
解析数据:
@interface ChangeAreaViewController () {
NSArray* provinceArray, *cityArray, *areaArray;
}
// 加载plist中的数据
- (void)loadData {
provinceArray = [[NSMutableArray alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"area.plist" ofType:nil]];
cityArray = [[provinceArray objectAtIndex:0] objectForKey:@"cities"];
areaArray = [[cityArray objectAtIndex:0] objectForKey:@"areas"];
}
这样我们便得到了plist中的全部省信息,以及第一个省的市区信息(这里默认展示第一行)。
下面设置列和行数
// DataSource
// 列数
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 3;
}
//行数
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
if (component == 0) {
return [provinceArray count];
} else if( component == 1 ) {
return [cityArray count];
} else {
return [areaArray count];
}
}
列数还是3,行数变成实际每列对应的行数。
实现自定义view的显示,以及滑动对应的逻辑关系
// 返回View
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view {
UILabel* myView = nil;
myView = [[UILabel alloc] init];
myView.textAlignment = NSTextAlignmentCenter;
myView.font = [UIFont systemFontOfSize:22]; //用label来设置字体大小
if (component == 0) {
myView.text =[[provinceArray objectAtIndex:row] objectForKey:@"state"];
} else if (component == 1) {
myView.text =[[cityArray objectAtIndex:row] objectForKey:@"city"];
} else {
myView.text =[areaArray objectAtIndex:row];
}
return myView;
}
// 滑动触发事件
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
if (component == 0) { //当是省的时候
cityArray = [[provinceArray objectAtIndex:row] objectForKey:@"cities"];
NSLog(@"%@", cityArray);
[self.pickerView reloadComponent:1];
[_pickerView selectRow:0 inComponent:1 animated:NO];
if ([cityArray count] != 0) {
areaArray = [[cityArray objectAtIndex:0] objectForKey:@"areas"];
[_pickerView selectRow:0 inComponent:2 animated:NO];
[_pickerView reloadComponent:2];
}
} else if (component == 1) {
areaArray = [[cityArray objectAtIndex:row] objectForKey:@"areas"];
[_pickerView selectRow:0 inComponent:2 animated:NO];
[_pickerView reloadComponent:2];
}
}
上面的方法很好理解,就是显示对应数据,不多赘述。
最核心的代码就是滑动后响应方法,当我们滑动数据为第0列时候,更新对应的第1列数据,如果第1列数据存在,那么请求第2列的数据,对应更新第二列的数据。
以上就是UIPickerView的简单实用,如有问题,敬请斧正。