UI--UIPickerView和UIDatePicker的總結,uidatepicker

來源:互聯網
上載者:User

UI--UIPickerView和UIDatePicker的總結,uidatepicker

回到頂部UIPickerView的主要方法和城市選取器的修正

UIPickerView只有兩個資料來源方法.要想完整地顯示出PickerView,需要結合使用代理方法 資料來源方法:

// 一共有多少組(列)- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView// 每列有多少行,傳入的參數component是對應的列- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component

UIPickerView的代理方法:

// 告訴系統每一行顯示什麼資料  通常可以結合switch case使用的- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component; // 監聽pickerView的點擊事件- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component;

一些其他的常用方法

// pickerView的對象方法,選擇指定列的指定行- (void)selectRow:(NSInteger)row inComponent:(NSInteger)component animated:(BOOL)animated// 對象方法,擷取指定列的當前選擇的行的行號,如果沒有選中任何行 就會返回-1- (NSInteger)selectedRowInComponent:(NSInteger)component;

城市選擇程式中同時修改省份和城市的時候,會造成程式崩潰的原因和修改方案:

在 這個項目中最容易出問題的地方是:每次選取器在變化的過程中,注意是變化的過程中,會不斷地調用下面兩個方法
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
在這兩個方法中,若是用這個方法以下方法擷取當前被選中的項
- (NSInteger)selectedRowInComponent:
這個方法返回的的值是變化的,因此若根據這個值計算com1的選中項的索引,很容易造成數組越界。 因此我的解決方案是用成員變數這個值。每次didSelected時,也就是已經確定值之後,改變這個固定的值。

1.首先增加類的成員屬性selectedRowOfComp1

2.在計算第二列也就是"城市"列的列數的時候按照成員屬性儲存的選擇的第一行進行計算。在pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component

if (component == 0) {    return self.provinces.count;}MKProvince *p = self.provinces[self.selectedRowOfComp1];return p.cities.count;
由此每行需要顯示資料的方法中也做了改動:
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{    if (component == 0) {        MKProvince *p = self.provinces[row];        return p.name;    } else {        MKProvince *p = self.provinces[self.selectedRowOfComp1];        return p.cities[row];    }}

3.當省份部分的資料選定之後,要修改成員屬性,並且重新整理城市部分的資料。在label中要顯示的城市和省份也是根據成員屬性值來計算的:

- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{    if (component == 0) {        MKProvince *p = self.provinces[row];        // 改變lbl的顯示        self.lblProvince.text = p.name;                // 改變城市組的顯示        self.selectedRowOfComp1 = row;        [pickerView reloadComponent:1]; // 這句話一定要在self.selectedRowOfComp1 = row;之後。  reloadComponent:1重新載入component1但是不會改變已經選中的行號,因此可能會造成已經選中的是第二行,對於省份變成重慶這樣的只有一個市的省份可能會引起bug,但是不會的,因為像這樣的情況reload會將城市的資料顯示為第一行        // 更新lblCity的資料        NSInteger cityIndex = [pickerView selectedRowInComponent:1];        self.lblCity.text = p.cities[cityIndex];// 上一句使得component1更新,這句保證了lbl和component1資料一致    } else {        MKProvince *p = self.provinces[self.selectedRowOfComp1];        // 改變lbl的顯示        self.lblCity.text = p.cities[row];    }}
回到頂部UIDatePicker的使用,並抽取為工具類

建立一個UIDatePicker

// 先建立dataPickerCGFloat width = [UIScreen mainScreen].bounds.size.width;UIDatePicker *datePicker = [[UIDatePicker alloc] initWithFrame:CGRectMake(0, 0, width, 180)];datePicker.locale = [NSLocale localeWithLocaleIdentifier:@"zh-Hans"]; // 設定預設的地區datePicker.datePickerMode = UIDatePickerModeDate; // 設定輸入的模式是日期self.datePicker = datePicker; // 設定為控制器的屬性self.txtTime.inputView = self.datePicker; // 將datePicker設定為textField控制項的輸入器// DatePicker輸入器的附屬viewUIToolbar *toolbar = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, width, 44)];UIBarButtonItem *item1 = [[UIBarButtonItem alloc] initWithTitle:@"上一個" style:UIBarButtonItemStylePlain target:self action:@selector(previous)];UIBarButtonItem *item2 = [[UIBarButtonItem alloc] initWithTitle:@"下一個" style:UIBarButtonItemStylePlain target:self action:@selector(next)];UIBarButtonItem *item3 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];UIBarButtonItem *item4 = [[UIBarButtonItem alloc] initWithTitle:@"完成" style:UIBarButtonItemStyleDone target:self action:@selector(done)]; // 設定完成的監聽事件toolbar.items = @[item1, item2, item3, item4]; self.txtTime.inputAccessoryView = toolbar; // 將toolbar設定為textField的輸入器附屬view

處理輸入完成後done按鈕的點擊事件

- (void)done{    [self.view endEditing:YES];    // 將選擇的日期格式化    NSDate *date = self.datePicker.date;    NSDateFormatter *fmt = [[NSDateFormatter alloc]init];    fmt.dateFormat = @"yyyy年MM月dd日";    NSString *dateStr = [fmt stringFromDate:date];    // 將格式化後的字串賦值給textField    self.txtTime.text = dateStr; }
抽取為工具類

建立工具類MKToolDatePicker,在MKToolDatePicker.h中

#import "MKTool.h"@class UITextField;@protocol MKToolDatePickerDelegate;/** *  建立後需要強引用這個類 */@interface MKToolDatePicker : MKTool/** *  指定要設定的UITextField控制項 */@property (nonatomic, weak) id delegate;- (void)datePickerOnTextField:(UITextField *)textField;@end@protocol MKToolDatePickerDelegate /** *  當點擊了時間選取器的"完成"按鈕,並且代理類(一般為控制器)已經實現了該方法的時候調用,用於處理選擇的NSDate * *  @param toolDatePicker 工具類對象本本身 *  @param textField      指定的textField *  @param date           點擊"完成"之前選擇的date */- (void)toolDatePicker:(MKToolDatePicker *)toolDatePicker onView:(UITextField *)textField didClickedDoneWithDate:(NSDate *)date;@end

在MKToolDatePicker.m中

#import "MKToolDatePicker.h"#import <UIKit/UIDatePicker.h>#import <UIKit/UIScreen.h>#import <UIKit/UIToolbar.h>@interface MKToolDatePicker ()@property (nonatomic, strong) UIDatePicker *datePicker;@property (nonatomic, strong) UIToolbar *toolBar;@property (nonatomic, weak) UITextField *textField;@end@implementation MKToolDatePicker- (UIDatePicker *)datePicker{    if (!_datePicker) {                // 先建立dataPicker        CGFloat width = [UIScreen mainScreen].bounds.size.width;        _datePicker = [[UIDatePicker alloc] initWithFrame:CGRectMake(0, 0, width, 180)];        _datePicker.locale = [NSLocale localeWithLocaleIdentifier:@"zh-Hans"];        _datePicker.datePickerMode = UIDatePickerModeDate;    }    return _datePicker;}- (UIToolbar *)toolBar{    if (!_toolBar) {        // 輸入的附屬view        _toolBar = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 44)];        UIBarButtonItem *item1 = [[UIBarButtonItem alloc] initWithTitle:@"上一個" style:UIBarButtonItemStylePlain target:self action:@selector(previous)];        UIBarButtonItem *item2 = [[UIBarButtonItem alloc] initWithTitle:@"下一個" style:UIBarButtonItemStylePlain target:self action:@selector(next)];        UIBarButtonItem *item3 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];        UIBarButtonItem *item4 = [[UIBarButtonItem alloc] initWithTitle:@"完成" style:UIBarButtonItemStyleDone target:self action:@selector(done)];        _toolBar.items = @[item1, item2, item3, item4];    }    return _toolBar;}- (void)datePickerOnTextField:(UITextField *)textField{    self.textField = textField;    textField.inputView = self.datePicker;        textField.inputAccessoryView = self.toolBar;}- (void)done{    [self.textField endEditing:YES];    if ([self.delegate respondsToSelector:@selector(toolDatePicker:onView:didClickedDoneWithDate:)]) {        [self.delegate toolDatePicker:self onView:self.textField didClickedDoneWithDate:self.datePicker.date];    }    }

在控制器中使用時間選取器工具類

#import "ViewController.h"#import "MKToolDatePicker.h"@interface ViewController () @property (weak, nonatomic) IBOutlet UITextField *txtTime;// 強引用時間選取器工具@property (nonatomic, strong) MKToolDatePicker *toolDatePicker;@end@implementation ViewController- (void)viewDidLoad {    [super viewDidLoad];        MKToolDatePicker *tool = [[MKToolDatePicker alloc]init];    self.toolDatePicker = tool;    tool.delegate = self; // 設定代理    [tool datePickerOnTextField:self.txtTime]; // 指定UITextView}// 根據onView的不同分別處理- (void)toolDatePicker:(MKToolDatePicker *)toolDatePicker onView:(UITextField *)textField didClickedDoneWithDate:(NSDate *)date{    NSDateFormatter *fmt = [[NSDateFormatter alloc]init];    fmt.dateFormat = @"yyyy年MM月dd日";    NSString *dateStr = [fmt stringFromDate:date];    self.txtTime.text = dateStr;}@end

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.