UITextField の inputView に UIPickerView を設定する
環境:iOS Deployment Target 7.1
以前、UIPickerView をキーボードのように表示・非表示させるというエントリーを書いたがもっと簡単なやり方を知ったのでメモしておく。
まず、以前のやり方は完了ボタンとそれを置くビューを自分で作って、UIPickerView といっしょに画面外から画面内に、画面内から画面外にアニメーションさせて移動させて表示・非表示を行っていた。
今回は UITextField を使い、その inputAccessoryView プロパティに UIBarButtonItem を、inputView プロパティに UIPickerView を設定するだけ。
このやり方なら表示・非表示の動作を自分で行わなくても UITextField にフォーカスが当たればキーボードのように下からシュッとアニメーションで現れるし、フォーカスが外れれば隠れる。
UITextField の inputView プロパティを使うことでキーボード以外が使えるのが目からうろこだった。
面白いのはキーボードは表示されないんだけどUIKeyboardWillShowNotification
やUIKeyboardWillHideNotification
などのキーボード表示・非表示時の Notification は通知されること。
サンプルコード
PickerViewController.m
#import "PickerViewController.h" #define TEXT_FIELDS_COUNT 2 #define GENDER_FIELD_TAG 1 #define AREA_FIELD_TAG 2 @interface PickerViewController () < UIPickerViewDelegate, UIPickerViewDataSource, UITextFieldDelegate > @property(nonatomic, retain) UIToolbar *keyboardToolbar; @property(nonatomic, strong) UITextField *genderTextField; @property(nonatomic, retain) UIPickerView *genderPickerView; @property(nonatomic, strong) UITextField *areaTextField; @property(nonatomic, retain) UIPickerView *areaPickerView; @property(nonatomic, strong) NSString *gender; @property(nonatomic, strong) NSString *area; @property(nonatomic, strong) NSArray *genderList; @property(nonatomic, strong) NSArray *areaList; @end @implementation PickerViewController {} - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor lightGrayColor]; self.genderList = @[@[@"1", @"男性"], @[@"2", @"女性"]]; self.areaList = @[@[@"1", @"北海道"], @[@"2", @"東北"], @[@"3", @"関東・信越"], @[@"4", @"東海・北陸・近畿"], @[@"5", @"中国・四国"], @[@"6", @"九州"], @[@"7", @"沖縄"]]; // Gender TextField self.genderTextField = [[UITextField alloc] initWithFrame:CGRectMake(0, 100, self.view.bounds.size.width, 40)]; self.genderTextField.delegate = self; self.genderTextField.tag = GENDER_FIELD_TAG; self.genderTextField.backgroundColor = [UIColor whiteColor]; [self.view addSubview:self.genderTextField]; // Area TextField self.areaTextField = [[UITextField alloc] initWithFrame:CGRectMake(0, 150, self.view.bounds.size.width, 40)]; self.areaTextField.delegate = self; self.areaTextField.tag = AREA_FIELD_TAG; self.areaTextField.backgroundColor = [UIColor whiteColor]; [self.view addSubview:self.areaTextField]; // Gender picker self.genderPickerView = [[UIPickerView alloc] init]; self.genderPickerView.delegate = self; self.genderPickerView.tag = GENDER_FIELD_TAG; self.genderPickerView.showsSelectionIndicator = YES; // Area picker self.areaPickerView = [[UIPickerView alloc] init]; self.areaPickerView.delegate = self; self.areaPickerView.tag = AREA_FIELD_TAG; self.areaPickerView.showsSelectionIndicator = YES; // Keyboard toolbar self.keyboardToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 38.0f)]; self.keyboardToolbar.barStyle = UIBarStyleBlackTranslucent; UIBarButtonItem *spaceBarItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]; UIBarButtonItem *doneBarItem = [[UIBarButtonItem alloc] initWithTitle:@"決定" style:UIBarButtonItemStyleDone target:self action:@selector(resignKeyboard:)]; [self.keyboardToolbar setItems:@[spaceBarItem, doneBarItem]]; self.genderTextField.inputAccessoryView = self.keyboardToolbar; self.genderTextField.inputView = self.genderPickerView; self.areaTextField.inputAccessoryView = self.keyboardToolbar; self.areaTextField.inputView = self.areaPickerView; } - (void)resignKeyboard:(id)sender { id firstResponder = [self getFirstResponder]; if ([firstResponder isKindOfClass:[UITextField class]]) { [firstResponder resignFirstResponder]; } } - (id)getFirstResponder { NSUInteger index = 0; while (index <= TEXT_FIELDS_COUNT) { UITextField *textField = (UITextField *)[self.view viewWithTag:index]; if ([textField isFirstResponder]) { return textField; } index++; } return NO; } - (void)checkSpecialFields:(NSUInteger)tag { if (tag == GENDER_FIELD_TAG && [self.genderTextField.text isEqualToString:@""]) { [self setGenderData]; } else if (tag == AREA_FIELD_TAG && [self.areaTextField.text isEqualToString:@""]) { [self setAreaData]; } } - (void)setGenderData { NSInteger row = [self.genderPickerView selectedRowInComponent:0]; self.genderTextField.text = self.genderList[row][1]; self.gender = self.genderList[row][0]; } - (void)setAreaData { NSInteger row = [self.areaPickerView selectedRowInComponent:0]; self.areaTextField.text = self.areaList[row][1]; self.area = self.areaList[row][0]; } #pragma mark - UITextFieldDelegate - (void)textFieldDidBeginEditing:(UITextField *)textField { NSUInteger tag = [textField tag]; [self checkSpecialFields:tag]; } - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { NSUInteger tag = [textField tag]; if (tag == GENDER_FIELD_TAG || tag == AREA_FIELD_TAG) { return NO; } return YES; } #pragma mark - UIPickerViewDataSource - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView { return 1; } - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component { NSUInteger tag = [pickerView tag]; if (tag == GENDER_FIELD_TAG) { return self.genderList.count; } else if (tag == AREA_FIELD_TAG) { return self.areaList.count; } return 0; } #pragma mark - UIPickerViewDelegate - (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component { NSUInteger tag = [pickerView tag]; if (tag == GENDER_FIELD_TAG) { return self.genderList[row][1]; } else if (tag == AREA_FIELD_TAG) { return self.areaList[row][1]; } return @""; } - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component { NSUInteger tag = [pickerView tag]; if (tag == GENDER_FIELD_TAG) { [self setGenderData]; } else if (tag == AREA_FIELD_TAG) { [self setAreaData]; } } @end
参考
davidebettio/DBSignupViewController · GitHub
https://github.com/davidebettio/DBSignupViewController