最终效果图:
Main.storyboard
KeyboardTool.xib
KeyboardTool.h
// KeyboardTool.h // 键盘处理 // Created by beyond on 14-8-24. // Copyright (c) 2014年 com.beyond. All rights reserved. #import <UIKit/UIKit.h> @protocol KeyboardToolDelegate; typedef enum { kKeyboardToolButtonTypeNext, // 下一个按钮 kKeyboardToolButtonTypePrevious, // 上一个按钮 kKeyboardToolButtonTypeDone // 完成按钮 } KeyboardToolButtonType; @interface KeyboardTool : UIToolbar // 上一个按钮控件 @property (nonatomic, weak) IBOutlet UIBarButtonItem *previousBtn; // 下一个按钮控件 @property (nonatomic, weak) IBOutlet UIBarButtonItem *nextBtn; // 完成按钮控件 @property (nonatomic, weak) IBOutlet UIBarButtonItem *doneBtn; // 代理一般用weak,同时,避免与默认的继承的delegate冲突 @property (nonatomic, weak) id<KeyboardToolDelegate> toolDelegate; // 类方法 返回一个实例对象 + (id)keyboardTool; // 监听工具条上 三个按钮的点击 事件 - (IBAction)previousBtnClicked; - (IBAction)nextBtnClicked; - (IBAction)doneBtnClicked; @end
KeyboardTool.m
// KeyboardTool.m // 键盘处理 // Created by beyond on 14-8-24. // Copyright (c) 2014年 com.beyond. All rights reserved. #import "KeyboardTool.h" #import "KeyboardToolDelegate.h" @implementation KeyboardTool // 类方法,从xib文件中初始化一个KeyboardTool + (id)keyboardTool { // owner可以传KeyboardTool这个类 // 点击"下一个"按钮的时候,要调用owner的next方法 NSArray *array = [[NSBundle mainBundle] loadNibNamed:@"keyboardTool" owner:nil options:nil]; // 返回初始化完毕的KeyboardTool对象 return array[0]; } #pragma mark - 点击事件 // 点击了上一个按钮 - (void)previousBtnClicked { if ([_toolDelegate respondsToSelector:@selector(keyboardTool:buttonType:)]) { // 告诉代理,点击的是上一个按钮 [_toolDelegate keyboardTool:self buttonType:kKeyboardToolButtonTypePrevious]; } } // 点击了下一个按钮 - (void)nextBtnClicked { if ([_toolDelegate respondsToSelector:@selector(keyboardTool:buttonType:)]) { // 告诉代理,点击的是下一个按钮 [_toolDelegate keyboardTool:self buttonType:kKeyboardToolButtonTypeNext]; } } // 点击了完成按钮 - (void)doneBtnClicked { if ([_toolDelegate respondsToSelector:@selector(keyboardTool:buttonType:)]) { // 告诉代理,点击的是完成按钮 [_toolDelegate keyboardTool:self buttonType:kKeyboardToolButtonTypeDone]; } } @end
KeyboardToolDelegate.h
// // KeyboardToolDelegate.h // 22_键盘综合案例 // // Created by beyond on 14-8-24. // Copyright (c) 2014年 com.beyond. All rights reserved. // #import <Foundation/Foundation.h> @class KeyboardTool; @protocol KeyboardToolDelegate <NSObject> - (void)keyboardTool:(KeyboardTool *)tool buttonType:(KeyboardToolButtonType)type; @end
BeyondViewController.h
// // BeyondViewController.h // 22_键盘综合案例 // // Created by beyond on 14-8-24. // Copyright (c) 2014年 com.beyond. All rights reserved. // #import <UIKit/UIKit.h> #import "KeyboardTool.h" #import "KeyboardToolDelegate.h" @interface BeyondViewController : UIViewController <UITextFieldDelegate, UIPickerViewDataSource, UIPickerViewDelegate, KeyboardToolDelegate> // 生日输入框 @property (weak, nonatomic) IBOutlet UITextField *birthdayTextField; // 城市输入框 @property (weak, nonatomic) IBOutlet UITextField *cityTextField; @end
BeyondViewController.m
// // BeyondViewController.m // 22_键盘综合案例 // // Created by beyond on 14-8-24. // Copyright (c) 2014年 com.beyond. All rights reserved. // #import "BeyondViewController.h" @interface BeyondViewController () // 所有省名组成的数组 @property (nonatomic, strong) NSArray *provinceNameArr; // 字典:省名key---value城市名组成的数组 @property (nonatomic, strong) NSDictionary *provinceName_cities_Dict; // 当前激活的活跃状态的输入框 @property (nonatomic, weak) UITextField *currentTextField; // 键盘上的工具条 @property (nonatomic, weak) KeyboardTool *tool; // 所有输入框控件 组成的数组 @property (nonatomic, strong) NSMutableArray *allTextFields; @end @implementation BeyondViewController - (void)viewDidLoad { [super viewDidLoad]; self.allTextFields = [NSMutableArray array]; // 类方法,实例化一个KeyboardTool对象 self.tool = [KeyboardTool keyboardTool]; self.tool.backgroundColor = [UIColor clearColor]; self.tool.barTintColor = [UIColor lightGrayColor]; // 并且设置键盘工具的代理为当前控制器,用于接收其内部的btn点击事件,感知btnType self.tool.toolDelegate = self; // 1.设置所有文本框的键盘工具条 都是 自定义的KeyboardTool for (UITextField *field in self.view.subviews) { // 如果不是文本输入框,继续 if (![field isKindOfClass:[UITextField class]]) continue; // 每一个文本输入框的键盘工具都是它... field.inputAccessoryView = self.tool; // 数组保存所有的文本输入框控件,后面要用到 [self.allTextFields addObject:field]; // 设置每个文本输入框的代理都是当前控制器 field.delegate = self; } // 2.为生日输入框,设置键盘为DatePicker [self setInputViewForBirthdayTextField]; // 3.为城市输入框,设置键盘为DatePicker [self setInputViewForCityTextField]; // 4.加载所有的数据 [self loadAllData]; } // 2.为生日输入框,设置键盘为DatePicker - (void)setInputViewForBirthdayTextField { // 设置生日的键盘(不用设置宽高和位置) UIDatePicker *datePicker = [[UIDatePicker alloc] init]; // 设置区域为中国简体中文 datePicker.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"zh_CN"]; // 模式为:只显示日期 datePicker.datePickerMode = UIDatePickerModeDate; // 监听datePicker的值改事件 [datePicker addTarget:self action:@selector(datePickerValueChangeed:) forControlEvents:UIControlEventValueChanged]; // 设置其为生日输入框的view self.birthdayTextField.inputView = datePicker; } // 3.为城市输入框,设置键盘为DatePicker - (void)setInputViewForCityTextField { // 设置城市的键盘 UIPickerView *picker = [[UIPickerView alloc] init]; // 设置数据源和代理 picker.dataSource = self; picker.delegate = self; // 显示指示器 picker.showsSelectionIndicator = YES; // 设置其为城市输入框的view self.cityTextField.inputView = picker; } // 4.加载所有的数据 - (void)loadAllData { // 加载省份数据 NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"cities" ofType:@"plist"]]; // 所有以省名组成的数组 self.provinceNameArr = dict[@"provinces"]; // 字典,键是省名,值是城市名组成的数组 self.provinceName_cities_Dict = dict[@"cities"]; } // 2.1监听生日选择控件的值改变事件,为生日输入框赋值 - (void)datePickerValueChangeed:(UIDatePicker *)picker { NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; formatter.dateFormat = @"yyyy-MM-dd"; // 生日输入框赋值 self.birthdayTextField.text = [formatter stringFromDate:picker.date]; } #pragma mark - PickerView数据源方法 // 一共多少列 - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView { // 第一列是省名,第二列是省名对应的城市数组 return 2; } // 每一列对应多少行 - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component { if (component == 0) { // 返回省名数组的长度 return self.provinceNameArr.count; } else { // 返回第1列 当前选中的行号 NSUInteger rowNum = [pickerView selectedRowInComponent:0]; // 先从省名数组,取出对应的省名 NSString *pName = self.provinceNameArr[rowNum]; // 再从字典中,通过省名,获取城市数组,并返回其长度 NSArray *cityArr = self.provinceName_cities_Dict[pName]; return cityArr.count; } } // 每列每行显示什么数据 - (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component { if (component == 0) { //前一列,显示省名 return self.provinceNameArr[row]; } else { // 返回第1列 当前选中的行号 NSUInteger rowNum = [pickerView selectedRowInComponent:0]; // 先从省名数组,取出对应的省名 NSString *pName = self.provinceNameArr[rowNum]; // 再从字典中,通过省名,获取城市数组,并返回其长度 NSArray *cityArr = self.provinceName_cities_Dict[pName]; return cityArr[row]; } } // UIPickerView选中了某一行就会调用 - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component { // 刷新后一列的数据,联动效果 [pickerView reloadComponent:1]; NSUInteger pRowNum = [pickerView selectedRowInComponent:0]; // 先从省名数组,取出对应的省名 NSString *pName = self.provinceNameArr[pRowNum]; NSUInteger cRowNum = [pickerView selectedRowInComponent:1]; // 再从字典中,通过省名,获取城市数组,并返回其对应的城市名 NSArray *cityArr = self.provinceName_cities_Dict[pName]; NSString *cName = cityArr[cRowNum]; // 城市输入框赋值 self.cityTextField.text = [NSString stringWithFormat:@"%@ %@", pName, cName]; } #pragma mark - 重点!!!!!!!!keyboardTool代理方法 - (void)keyboardTool:(KeyboardTool *)tool buttonType:(KeyboardToolButtonType)type { if (type == kKeyboardToolButtonTypeDone) { //当点击完成时,当前活动的输入框,取消第一响应者,退出键盘 [self.currentTextField resignFirstResponder]; } else { //先取出当前输入框在输入框数组中的索引, NSUInteger index = [self.allTextFields indexOfObject:self.currentTextField]; if (type == kKeyboardToolButtonTypePrevious) { //当点击上一个时,索引减1, index--; } else { //当点击下一个时,索引加1, index++; } // 取出对应索引的输入框,成为即将成为的第一响应者,调出对应的键盘 UITextField *field = self.allTextFields[index]; [field becomeFirstResponder]; } } #pragma mark - 重点!!!!!!!UITextField代理方法 - (void)textFieldDidBeginEditing:(UITextField *)textField { // 记住被激活的文本框,其他方法keyboardTool:buttonClick:中要用到 self.currentTextField = textField; // 先取得本输入框在所有输入框组成的数组中的索引 NSUInteger index = [self.allTextFields indexOfObject:textField]; // 设置下一个按钮的,是否可用 self.tool.nextBtn.enabled = index != self.allTextFields.count - 1; // 设置上一个按钮的,是否可用 self.tool.previousBtn.enabled = index != 0; } // 这个是 UITextField的一个委托方法! // 利用这个委托 我们在打开键盘的时候,点击return 就可以关闭键盘了 - (BOOL)textFieldShouldReturn:(UITextField *)textField { // 结束所有编辑,退出所有键盘,并且返回YES就可以 [self.view endEditing:YES]; return YES; } @end
数据源
时间: 2024-11-08 03:34:52