作者:KevinTing
前幾天在項目中碰到一個這樣的需求:需要在textField中輸入日期,輸入的時候彈出datePicker選擇日期。心想很簡單啊,無非就是把textField的inputView屬性設置為UIDatePicker的實例即可啊。然後在UIDatePicker的pickerValueChanged事件中更新textField的值就可以了啊。我開始是這麼做的:
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. UIDatePicker *picker = [[UIDatePicker alloc] init]; picker.datePickerMode = UIDatePickerModeDate; [picker addTarget:self action:@selector(pickerValueChanged:) forControlEvents:UIControlEventValueChanged]; self.firstTextField.inputView = picker; } - (void)pickerValueChanged:(UIDatePicker *)sender { NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; [formatter setDateFormat:@"yyyy-MM-dd"]; self.firstTextField.text = [formatter stringFromDate:sender.date]; }
恩,運行的很好。等等,老板來了說一句,這麼快搞好了啊,那這個view上面再加幾個日期輸入框吧。客戶查詢起始時間,還要有結束時間啊。好吧,這個也不難的,拉一個textField。如法炮制,在viewDidLoad屁股後面加上:
self.secondTextField.inputView = picker;
然後為了避免輸入沖突,在textField的delegate方法中記錄當前輸入框:
- (void)textFieldDidBeginEditing:(UITextField *)textField { self.currentDateTextField = textField; }
並修改pickerValueChanged方法。
- (void)pickerValueChanged:(UIDatePicker *)sender { NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; [formatter setDateFormat:@"yyyy-MM-dd"]; self.currentDateTextField.text = [formatter stringFromDate:sender.date]; }
ok了。但是,後面做的過程中發現這個界面不只有輸入日期的textField,還有其他的普通textField啊。那只能修改currentDateTextField的記錄條件了。
- (void)textFieldDidBeginEditing:(UITextField *)textField { if (textField == self.firstTextField || textField == self.secondTextField) { self.currentDateTextField = textField; } }
好的,這個界面搞定了,老板又來說。後面有幾個界面也是這樣的,需要加幾個日期選擇輸入框。媽蛋啊!那不是又得再其他的viewController中加入這些代碼,設置delegate,實現delegate方法。實話說,這代碼量也不大啊。但是這個代碼放到viewController中,一是無法復用,二是這樣寫好慫 啊!代碼都是一樣的,應該抽出來復用啊!
於是,我寫了一個textField的category,直接用一個屬性datePickerInput來設置UIDatePicker的鍵盤。下面是頭文件:
#import [UIKit/UIKit.h](因識別問題,這裡將尖括號改為方括號) @interface UITextField (DatePicker) @property (nonatomic, assign) BOOL datePickerInput; + (UIDatePicker *)sharedDatePicker; @end
下面是m文件:
#import "UITextField+DatePicker.h" @implementation UITextField (DatePicker) // 1 + (UIDatePicker *)sharedDatePicker; { static UIDatePicker *daterPicker = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ daterPicker = [[UIDatePicker alloc] init]; daterPicker.datePickerMode = UIDatePickerModeDate; }); return daterPicker; } // 2 - (void)datePickerValueChanged:(UIDatePicker *)sender { if (self.isFirstResponder) { NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; [formatter setDateFormat:@"yyyy-MM-dd"]; self.text = [formatter stringFromDate:sender.date]; } } // 3 - (void)setDatePickerInput:(BOOL)datePickerInput { if (datePickerInput) { self.inputView = [UITextField sharedDatePicker]; [[UITextField sharedDatePicker] addTarget:self action:@selector(datePickerValueChanged:) forControlEvents:UIControlEventValueChanged]; } else { self.inputView = nil; [[UITextField sharedDatePicker] removeTarget:self action:@selector(datePickerValueChanged:) forControlEvents:UIControlEventValueChanged]; } } // 4 - (BOOL)datePickerInput { return [self.inputView isKindOfClass:[UIDatePicker class]]; } end
代碼很簡單,1處是套用單例的寫法初始化一個全局的datePicker;2處設置text,此處必須判斷是不是isFirstResponder;3和4是setter和getter。
後面再加上日期選擇輸入框的時候,只需要這樣寫就行了:
self.firstTextField.datePickerInput = YES; self.secondTextField.datePickerInput = YES;
恩,比之前好多了!
完整的demo項目在這裡:https://github.com/tujinqiu/KTTextFieldDatePickerKeyBoard