本来这篇想写UICollectionView的,但是上午写了一个demo不是很满意,并且我自己在开发中使用的较少,就留着以后再写吧,今天先来总结一下UIPickerView,这个控件也是一个比较常用的控件,使用场景比较多,比如一些地区选择,分类选择等。
对UIPickerView的封装还有一个UIDatePicker控件,这个是系统对UIPickerView的封装,专门用于日期的选择,使用和UIPickerView差不多,这里就直接总结一些UIPickerView的使用。
#import "ViewController.h"
//准守协议
@interface ViewController ()
{
//声明pickerView和数据源
UIPickerView *pickerView;
NSMutableArray *dataSource;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self createDataSource];
[self createPickerView];
}
//创建pickerView
- (void)createPickerView{
pickerView = [[UIPickerView alloc] initWithFrame:CGRectMake(0, 100, self.view.frame.size.width, 300)];
pickerView.backgroundColor = [UIColor grayColor];
pickerView.delegate = self;
pickerView.dataSource = self;
[self.view addSubview:pickerView];
}
//创建数据源
- (void)createDataSource{
dataSource = [NSMutableArray arrayWithCapacity:0];
for (int i=0; i<10; i++) {
[dataSource addObject:[NSString stringWithFormat:@"第%.2d行数据", i+1]];
}
}
//下面实现协议方法
//1、设置pickerView的列数
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
return 1;
}
//2、设置pickerView每一列的行数
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{
return dataSource.count;
}
//3、给每一行添加文本
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{
return dataSource[row];
}
//4、当滚动到某一行停止时出发的方法处理
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
NSLog(@"选择的是:%@", dataSource[row]);
}
@end
在上面的代码中,完整的实现了一个简单的单列pickerView。使用简单方便。
但是在实际的开发中对于pickerView的使用常是一种多列使用,并且在多列的基础上加上了数据联动。对于这样的情况就要有一个清晰的思路,将需求进行分析。
比如:要求制作一个地区选择器,要求省市联动,也就是说当第一列为选择安徽省的时候,第二列会出现安徽省的一些市。这样的就要写一个双列的picker,并且第二行的数据要根据第一行显示。
我在UITableView的最后总结中说过,对于界面的动态处理其实都是对于数据的动态处理,通过数据的变化来实现在这里也是可行的。而且深入思考这确实不是视图的变换而是数据的联动。好了,说了这么多废话下面我们来改一下上面的代码,实现一个两列联动的pickerView。
首先在上面的代码中修改4点:
1、修改数据源,这里需要两个数据源,第一个存储省的数据,第二个存储每个省下的市的数据。还有一个字符串,存储选择的省
//声明pickerView和数据源
UIPickerView *myPickerView;
//省数据,一个数组
NSMutableArray *provinces;
//城市数据,一个字典
NSMutableDictionary *citys;
//设置一个全局变量存储第一列选择的数据,本例中是选择的省
NSString *select;
- (void)createDataSource{
select = @"安徽";
provinces = [NSMutableArray arrayWithArray:@[@"安徽",@"河北",@"江苏",@"浙江",@"北京",@"上海"]];
NSDictionary *dict = @{@"安徽":@[@"合肥",@"芜湖",@"六安",@"亳州",@"黄山"],
@"河北":@[@"石家庄",@"保定",@"衡水",@"沧州"],
@"江苏":@[@"南京",@"苏州",@"无锡",@"扬州",@"常州"],
@"浙江":@[@"杭州",@"宁波",@"金华",@"温州"],
@"北京":@[@"北京"],
@"上海":@[@"上海"]
};
citys = [NSMutableDictionary dictionaryWithDictionary:dict];
}
2、在代理方法中修改列数为两列,行的数据根据数组决定
//1、设置pickerView的列数
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
return 2;
}
//2、设置pickerView每一列的行数
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{
if (component == 0) {
return provinces.count;
}else{
return [[citys objectForKey:select] count];
}
}
3、修改展示文本:
//3、给每一行添加文本
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{
if (component == 0) {
return provinces[row];
}else{
return [[citys objectForKey:select]objectAtIndex:row];
}
}
4、选择处理修改:
//4、当滚动到某一行停止时出发的方法处理
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
if (component == 0) {
select = provinces[row];
[myPickerView reloadComponent:1];
}
NSLog(@"你选择的是%@省%@市", select, [[citys objectForKey:select] objectAtIndex:row]);
}
下面是完整代码:
#import "ViewController.h"
//准守协议
@interface ViewController ()
{
//声明pickerView和数据源
UIPickerView *myPickerView;
//省数据,一个数组
NSMutableArray *provinces;
//城市数据,一个字典
NSMutableDictionary *citys;
//设置一个全局变量存储第一列选择的数据,本例中是选择的省
NSString *select;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self createDataSource];
[self createPickerView];
}
//创建pickerView
- (void)createPickerView{
myPickerView = [[UIPickerView alloc] initWithFrame:CGRectMake(0, 100, self.view.frame.size.width, 300)];
myPickerView.backgroundColor = [UIColor grayColor];
myPickerView.delegate = self;
myPickerView.dataSource = self;
[self.view addSubview:myPickerView];
}
//创建数据源
- (void)createDataSource{
select = @"安徽";
provinces = [NSMutableArray arrayWithArray:@[@"安徽",@"河北",@"江苏",@"浙江",@"北京",@"上海"]];
NSDictionary *dict = @{@"安徽":@[@"合肥",@"芜湖",@"六安",@"亳州",@"黄山"],
@"河北":@[@"石家庄",@"保定",@"衡水",@"沧州"],
@"江苏":@[@"南京",@"苏州",@"无锡",@"扬州",@"常州"],
@"浙江":@[@"杭州",@"宁波",@"金华",@"温州"],
@"北京":@[@"北京"],
@"上海":@[@"上海"]
};
citys = [NSMutableDictionary dictionaryWithDictionary:dict];
}
//下面实现协议方法
//1、设置pickerView的列数
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
return 2;
}
//2、设置pickerView每一列的行数
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{
if (component == 0) {
return provinces.count;
}else{
return [[citys objectForKey:select] count];
}
}
//3、给每一行添加文本
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{
if (component == 0) {
return provinces[row];
}else{
return [[citys objectForKey:select]objectAtIndex:row];
}
}
//4、当滚动到某一行停止时出发的方法处理
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
if (component == 0) {
select = provinces[row];
[myPickerView reloadComponent:1];
}
NSLog(@"你选择的是%@省%@市", select, [[citys objectForKey:select] objectAtIndex:row]);
}
// UIPickerView中指定列的宽度
-(CGFloat)pickerView:(UIPickerView *)pickerView
widthForComponent:(NSInteger)component
{
// 如果是第一列,宽度为90
if(component == 0) {
return 90;
}else
return 210; // 如果是其他列(只有第二列),宽度为210
}
@end
从上面的代码中就可以看出,一个联动的选择器其实也是很简单的,主要还是对于数据源的处理,还有就是既然是联动,那么在第一列动态变化的时候处理好第二列的展示逻辑。
好了,UIPickerView就简单的实现了一下。总体还是比较简单的。
关于UIDatePicker就不写了,主要注意时间格式就基本上没什么问题,和UIPickerView差不多的使用方式。