Apple提供了兩種形式的選擇器:日期選擇器(UIDatePicker)與自定義選擇器(UIPickerView)。
當用戶使用日期選擇器選定一個時間后,調用datePickerID.date可以直接獲得一個NSDate對象,從而可以進行一系列的時間與日期處理。
自定義選擇器的使用稍微麻煩點,當你直接從控件欄里拖放Picker View到故事板然后運行,會發現調試器界面空無一物。這是因為UIPickerView必須用代碼實現一些協議才能正常顯示。而且無法在Attributes Inspector中配置選擇器視圖的外觀。
自定義選擇器需要遵守兩個協議:數據源協議和委托協議。
1. 數據源協議
數據源協議(UIPickerViewDataSource)用來描述選擇器顯示多少信息。有下面兩個主要方法:
numberOfComponentInPickerView -- 返回選擇器的組件數
pickerView:numberOfRowsInComponent -- 返回指定組件包含多少行(不同的輸入值)
例如,如果要創建一個選擇器,顯示兩列,其中第一列包含一個可供選擇的值,而第二列包含兩個,則代碼實現如下:
@interface ViewController : UIViewController <UIPickerViewDataSource> - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView { return 2; //顯示兩列 } - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component { if(component==0) { //如果是第一列,顯示1個標簽 return 1; } else { //否則顯示2個標簽 return 2; } }
2. 委托協議
委托協議(UIPickerViewDelegate)負責創建和使用選擇器的系列工作。它負責將合適的數據傳遞給選擇器進行顯示,並確定用戶是否做出了選擇。該協議包含多個方法,但只有兩個是必不可少的:
pickerView:titleForRow:forComponent -- 根據指定的組件和行號返回該行的標題,即應向用戶顯示的字符串
pickerView:didSelectRow:inComponent -- 當用戶在選擇器中做出選擇時,將調用該委托方法,並向它傳遞用戶選擇的行號以及用戶最后觸摸的組件
UIPickView還有一個實例方法- (NSInteger)selectedRowInComponent:(NSInteger)component,用來返回指定列當前選擇的行數。通常和pickerView:didSelectRow:inComponent配合使用。想象這樣的情況:選擇器有兩列,第一列是國家,第二列是地區。假如你先轉動了國家,這個時候你想得到默認選擇的地區,就只能通過selectedRowInComponent來取得。(這個時候didSelectRow得到的row值,是國家那一列的)
@interface ViewController : UIViewController <UIPickerViewDataSource,UIPickerViewDelegate> - (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component { if(component==0) { //如果是第一列,顯示"中國" return @"中國"; } else { if(row==0) { return @"北京"; } else { return @"香港"; } } } - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component { if(component==0) { NSLog(@"用戶選擇了第一列"); } else { NSLog(@"用戶選擇了第二列"); NSLog(@"用戶選擇了第%d行",row); } }
還有一些非必要,但是也很有用的方法:
pickerView:rowHeightForComponent -- 給指定組件返回(設置)行高,單位為像素
pickerView:widthForComponent -- 給指定組件返回(設置)寬度,單位為像素
pickerView:viewForRow:viewForComponent:ReusingView -- 給指定組件和行號返回相應位置應顯示的自定義視圖,優先級高於pickerView:titleForRow:forComponent
- (CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component { if(component==0) { //設置第一列的行高 return 50; } else { return 30; } } - (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component { if(component==0) { //設置第一列的寬度 return 100; } else { return 80; } } - (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view { if(component==0) { //第一列返回一個Label組件 UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 75, 32)]; label.backgroundColor = [UIColor greenColor]; label.textColor = [UIColor redColor]; label.text = @"First"; return label; } else { //第二列返回一個圖片組件 if(row==0) { return [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"Orange.gif"]]; } else { return [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"Strawberry.gif"]]; } } }
UIDatePicker有一個實例方法setDate:animated,以編程的方式選擇日期。
UIPickerView有一個實例方法selectRow:inComponent:animated,以編程的方式來選擇值。