本來這篇想寫UICollectionView的,但是上午寫了一個demo不是很滿意,並且我自己在開發中使用的較少,就留着以後再寫吧,今天先來總結一下UIPickerView,這個控件也是一個比較常用的控件,使用場景比較多,比如一些地區選擇,分類選擇等。
對UIPickerView的封裝還有一個UIDatePicker控件,這個是系統對UIPickerView的封裝,專門用於日期的選擇,使用和UIPickerView差不多,這裏就直接總結一些UIPickerView的使用。
代碼實例
#import "ViewController.h"
//準守協議
@interface ViewController ()<UIPickerViewDelegate, UIPickerViewDataSource>
{
//聲明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 ()<UIPickerViewDelegate, UIPickerViewDataSource>
{
//聲明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差不多的使用方式。