首页 > 代码库 > 键盘处理例子思路
键盘处理例子思路
键盘处理例子思路
步骤一:简单搭建界面
步骤二、自定义XIB,用来描述性别
+ (id)sexBox
{
return [[NSBundle mainBundle] loadNibNamed:@"MJSexBox"owner:niloptions:nil][0];
}
2.1监听性别按钮点击,修改按钮的状态
#pragma mark改变了性别选择
- (IBAction)sexChange {
if (_manBtn.enabled) {//点击了男的
_manBtn.enabled = NO;
_womanBtn.enabled = YES;
} else { // 点击了女的
_manBtn.enabled = YES;
_womanBtn.enabled = NO;
}
}
2.2.在控制器中添加性别选择控件
MJSexBox *sexBox = [MJSexBox sexBox];
sexBox.center = CGPointMake(150, 70);
[self.view addSubview:sexBox];
步骤三:自定义键盘
3.1.设置生日键盘
// 1.1.生日
UIDatePicker *datePicker = [[UIDatePicker alloc] init];
datePicker.datePickerMode = UIDatePickerModeDate; // 只显示日期5
datePicker.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"zh_CN"];
[datePicker addTarget:selfaction:@selector(birthdayChange:) forControlEvents:UIControlEventValueChanged];
_birthdayField.inputView = datePicker; // 设置键盘为日期选择控件
_birthdayField.delegate = self;
3.2禁止生日键盘输入文字
#pragma mark - UITextField代理
#pragma mark 每当用户输入文字的时候就会调用这个方法,返回NO,禁止输入;但会YES,允许输入
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
return NO;
}
3.3监听生日键盘的值改变事件
#pragma mark -生日改变
- (void)birthdayChange:(UIDatePicker *)picker
{
// 1.取得当前时间
NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
fmt.dateFormat = @"yyyy-MM-dd";
NSString *time = [fmt stringFromDate:picker.date];
// 2.赋值到文本框
_birthdayField.text = time;
}
步骤四、设置城市
4.1用xib描述城市键盘,并且设置UIPickerView的代理和数据源,创建自定义视图。
+ (id)cityPicker
{
return [[NSBundle mainBundle] loadNibNamed:@"MJCityPicker"owner:niloptions:nil][0];
}
4.2加载数据,在awakeFromNib中调用
#pragma mark任何对象从xib中创建完毕的时候都会调用一次
- (void)awakeFromNib
{
NSArray *array = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"cities.plist"ofType:nil]];
_provinces = [NSMutableArray array];
for (NSDictionary *dictin array) {
MJProvince *p = [MJProvince provinceWithDict:dict];
[_provinces addObject:p];
}
}
4.3实现数据源和代理方法。
#pragma mark - UIPickerView数据源方法
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 2;
}
#pragma mark第component列有多少行数据
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
if (component ==0) {//多少个省份
return _provinces.count;
} else { // 当前选中省份的行数(城市个数)
// 1.获得选中了哪一个省
int pIndex = [pickerView selectedRowInComponent:0];
// 2.取出省份模型
MJProvince *p = _provinces[pIndex];
// 3.返回当前省份城市的个数
return p.cities.count;
}
}
#pragma mark - UIPickerView代理方法
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
if (component ==0) {//显示哪个省份
// 1.取出省份模型
MJProvince *p = _provinces[row];
// 2.取出省份名称
return p.name;
} else { // 显示哪个城市
// 1.获得选中了哪一个省
int pIndex = [pickerView selectedRowInComponent:0];
// 2.取出省份模型
MJProvince *p = _provinces[pIndex];
// 3.返回对应行的城市名称
return p.cities[row];
}
}
#pragma mark监听选中了某一列的某一行
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
if (component ==0) {//改变了省份
// 刷新第1列的数据(重新刷新数据,重新调用数据源和代理的相应方法获得数据)
[pickerView reloadComponent:1];
// 选中第1列的第0行
[pickerView selectRow:0inComponent:1animated:YES];
}
// 更改文字
// 1.获得选中的省份名称
int pIndex = [pickerView selectedRowInComponent:0];
MJProvince *p = _provinces[pIndex];
// 2.获得选中的城市位置
int cIndex = [pickerView selectedRowInComponent:1];
// 3.通知代理
if ([_delegate respondsToSelector:@selector(cityPicker:citySelectWithProvince:city:)]) {
[_delegate cityPicker:selfcitySelectWithProvince:p.name city:p.cities[cIndex]];
}
}
4.4调用自定义视图设置城市键盘
设置城市
MJCityPicker *cityPicker = [MJCityPicker cityPicker];
cityPicker.delegate = self;
_cityField.inputView = cityPicker; // 设置键盘为pickerview
_cityField.delegate = self;
#pragma mark - MJCityPicker代理方法
#pragma mark 选中了某个城市就会调用
- (void)cityPicker:(MJCityPicker *)cityPicker citySelectWithProvince:(NSString *)province city:(NSString *)city
{
_cityField.text = [NSString stringWithFormat:@"%@ %@", province, city];
}
4.5 给自定义城市键盘声明一个协议,并添加一个代理属性,当滚动键盘的时候,通知代理做些事情.
@protocolMJCityPickerDelegate <NSObject]]>
@optional
- (void)cityPicker:(MJCityPicker *)cityPicker citySelectWithProvince:(NSString *)province city:(NSString *)city;
@end
4.6在控制器中实现代理协议的方法。
#pragma mark - MJCityPicker代理方法
#pragma mark 选中了某个城市就会调用
- (void)cityPicker:(MJCityPicker *)cityPicker citySelectWithProvince:(NSString *)province city:(NSString *)city
{
_cityField.text = [NSString stringWithFormat:@"%@ %@", province, city];
}
步骤二、自定义XIB,用来描述性别
+ (id)sexBox
{
return [[NSBundle mainBundle] loadNibNamed:@"MJSexBox"owner:niloptions:nil][0];
}
2.1监听性别按钮点击,修改按钮的状态
#pragma mark改变了性别选择
- (IBAction)sexChange {
if (_manBtn.enabled) {//点击了男的
_manBtn.enabled = NO;
_womanBtn.enabled = YES;
} else { // 点击了女的
_manBtn.enabled = YES;
_womanBtn.enabled = NO;
}
}
2.2.在控制器中添加性别选择控件
MJSexBox *sexBox = [MJSexBox sexBox];
sexBox.center = CGPointMake(150, 70);
[self.view addSubview:sexBox];
步骤三:自定义键盘
3.1.设置生日键盘
// 1.1.生日
UIDatePicker *datePicker = [[UIDatePicker alloc] init];
datePicker.datePickerMode = UIDatePickerModeDate; // 只显示日期5
datePicker.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"zh_CN"];
[datePicker addTarget:selfaction:@selector(birthdayChange:) forControlEvents:UIControlEventValueChanged];
_birthdayField.inputView = datePicker; // 设置键盘为日期选择控件
_birthdayField.delegate = self;
3.2禁止生日键盘输入文字
#pragma mark - UITextField代理
#pragma mark 每当用户输入文字的时候就会调用这个方法,返回NO,禁止输入;但会YES,允许输入
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
return NO;
}
3.3监听生日键盘的值改变事件
#pragma mark -生日改变
- (void)birthdayChange:(UIDatePicker *)picker
{
// 1.取得当前时间
NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
fmt.dateFormat = @"yyyy-MM-dd";
NSString *time = [fmt stringFromDate:picker.date];
// 2.赋值到文本框
_birthdayField.text = time;
}
步骤四、设置城市
4.1用xib描述城市键盘,并且设置UIPickerView的代理和数据源,创建自定义视图。
+ (id)cityPicker
{
return [[NSBundle mainBundle] loadNibNamed:@"MJCityPicker"owner:niloptions:nil][0];
}
4.2加载数据,在awakeFromNib中调用
#pragma mark任何对象从xib中创建完毕的时候都会调用一次
- (void)awakeFromNib
{
NSArray *array = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"cities.plist"ofType:nil]];
_provinces = [NSMutableArray array];
for (NSDictionary *dictin array) {
MJProvince *p = [MJProvince provinceWithDict:dict];
[_provinces addObject:p];
}
}
4.3实现数据源和代理方法。
#pragma mark - UIPickerView数据源方法
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 2;
}
#pragma mark第component列有多少行数据
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
if (component ==0) {//多少个省份
return _provinces.count;
} else { // 当前选中省份的行数(城市个数)
// 1.获得选中了哪一个省
int pIndex = [pickerView selectedRowInComponent:0];
// 2.取出省份模型
MJProvince *p = _provinces[pIndex];
// 3.返回当前省份城市的个数
return p.cities.count;
}
}
#pragma mark - UIPickerView代理方法
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
if (component ==0) {//显示哪个省份
// 1.取出省份模型
MJProvince *p = _provinces[row];
// 2.取出省份名称
return p.name;
} else { // 显示哪个城市
// 1.获得选中了哪一个省
int pIndex = [pickerView selectedRowInComponent:0];
// 2.取出省份模型
MJProvince *p = _provinces[pIndex];
// 3.返回对应行的城市名称
return p.cities[row];
}
}
#pragma mark监听选中了某一列的某一行
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
if (component ==0) {//改变了省份
// 刷新第1列的数据(重新刷新数据,重新调用数据源和代理的相应方法获得数据)
[pickerView reloadComponent:1];
// 选中第1列的第0行
[pickerView selectRow:0inComponent:1animated:YES];
}
// 更改文字
// 1.获得选中的省份名称
int pIndex = [pickerView selectedRowInComponent:0];
MJProvince *p = _provinces[pIndex];
// 2.获得选中的城市位置
int cIndex = [pickerView selectedRowInComponent:1];
// 3.通知代理
if ([_delegate respondsToSelector:@selector(cityPicker:citySelectWithProvince:city:)]) {
[_delegate cityPicker:selfcitySelectWithProvince:p.name city:p.cities[cIndex]];
}
}
4.4调用自定义视图设置城市键盘
设置城市
MJCityPicker *cityPicker = [MJCityPicker cityPicker];
cityPicker.delegate = self;
_cityField.inputView = cityPicker; // 设置键盘为pickerview
_cityField.delegate = self;
#pragma mark - MJCityPicker代理方法
#pragma mark 选中了某个城市就会调用
- (void)cityPicker:(MJCityPicker *)cityPicker citySelectWithProvince:(NSString *)province city:(NSString *)city
{
_cityField.text = [NSString stringWithFormat:@"%@ %@", province, city];
}
4.5 给自定义城市键盘声明一个协议,并添加一个代理属性,当滚动键盘的时候,通知代理做些事情.
@protocolMJCityPickerDelegate <NSObject]]>
@optional
- (void)cityPicker:(MJCityPicker *)cityPicker citySelectWithProvince:(NSString *)province city:(NSString *)city;
@end
4.6在控制器中实现代理协议的方法。
#pragma mark - MJCityPicker代理方法
#pragma mark 选中了某个城市就会调用
- (void)cityPicker:(MJCityPicker *)cityPicker citySelectWithProvince:(NSString *)province city:(NSString *)city
{
_cityField.text = [NSString stringWithFormat:@"%@ %@", province, city];
}
步骤五:工具条
5.1自定义一个xib描述工具条
+ (id)keyboardTool
{
return [[NSBundle mainBundle] loadNibNamed:@"MJKeyboardTool"owner:niloptions:nil][0];
}
5.2将toolbar用view包装起来,目的不让外界修改toolbar,因为外界拿到的是UIView,而不是toolbar,就不能直接获取toolbar里面的属性了。
5.1自定义一个xib描述工具条
+ (id)keyboardTool
{
return [[NSBundle mainBundle] loadNibNamed:@"MJKeyboardTool"owner:niloptions:nil][0];
}
5.2将toolbar用view包装起来,目的不让外界修改toolbar,因为外界拿到的是UIView,而不是toolbar,就不能直接获取toolbar里面的属性了。
5.3自定义一个自定义工具条类,和xib绑定。
- (IBAction)previous;//上一个
- (IBAction)next;//下一个
- (IBAction)done;//完成
5.4 定义一个协议,通知代理按钮点击事件
@optional
- (void)keyboardTool:(MJKeyboardTool *)keyboardTool itemClick:(MJKeyboardToolItemType)itemType;
@end
5.5定义一个枚举类型,区分按钮
typedefenum {
MJKeyboardToolItemTypePrevious, // 上一个
MJKeyboardToolItemTypeNext, // 下一个
MJKeyboardToolItemTypeDone // 完成
} MJKeyboardToolItemType;
5.6当点击按钮时,通知代理
#pragma mark上一个
- (void)previous
{
// 通知代理(上一个按钮被点击了)
if ([_delegate respondsToSelector:@selector(keyboardTool:itemClick:)]) {
[_delegate keyboardTool:selfitemClick:MJKeyboardToolItemTypePrevious];
}
}
#pragma mark下一个
- (void)next
{
// 通知代理(下一个按钮被点击了)
if ([_delegate respondsToSelector:@selector(keyboardTool:itemClick:)]) {
[_delegate keyboardTool:selfitemClick:MJKeyboardToolItemTypeNext];
}
}
#pragma mark完成
- (void)done
{
// 通知代理(完成按钮被点击了)
if ([_delegate respondsToSelector:@selector(keyboardTool:itemClick:)]) {
[_delegate keyboardTool:selfitemClick:MJKeyboardToolItemTypeDone];
}
}
5.7 让控制器作为工具条的代理,并实现工具条代理方法
#pragma mark - MJKeyboardTool代理方法
#pragma mark 点击了工具条上面的按钮就会调用
- (void)keyboardTool:(SUNKeyboardTool*)keyboardTool itemClick:(SUNKeyboardToolItemType)itemType
{
if (itemType ==doneKeyboardToolItemType) {
[self.viewendEditing:YES];
}else{
int index = [_fieldsindexOfObject:_focusedField];
if (itemType ==previousKeyboardToolItemType) {
index--;
}else{
index++;
}
// 变成第一响应者
[_fields[index]becomeFirstResponder];
}
}
5.8监听所有文本框的开始编辑,设置所有文本框的代理为控制器
// 3.获得所有的文本输入框
MJKeyboardTool *tool = [MJKeyboardTool keyboardTool];
tool.delegate = self;
for(UIView *child in self.view.subviews) {
// 如果是文本输入框,就设置工具条
if ([child isKindOfClass:[UITextField class]]) {
UITextField *field = (UITextField *)child;
field.inputAccessoryView = tool;
}
}
5.9判断工具条上的按钮是否能点击
#pragma mark - UITextField代理
#pragma mark - 开始点击文本框的时候调用
- (void)textFieldDidBeginEditing:(UITextField*)textField
{
_focusedField = textField;
int index = [_fieldsindexOfObject:_focusedField];
_keyboardTool.previousBtm.enabled= (index != 0);
_keyboardTool.nextBtm.enabled= (index != (_fields.count- 1));
}
5.10监听系统发出键盘滚动通知
#pragma mark -监听系统发出的通知
- (void)addkeyboard
{
NSNotificationCenter *center = [NSNotificationCenterdefaultCenter];
// 监听键盘将要显示
[center addObserver:selfselector:@selector(showKeyboard:)name:UIKeyboardWillShowNotificationobject:nil];
// 监听键盘将要隐藏
[center addObserver:selfselector:@selector(keyboardWillHide:)name:UIKeyboardWillHideNotificationobject:nil];
}
5.11当键盘挡住文本框将视图往上移
#pragma mark -监听键盘将要显示
- (void)showKeyboard:(NSNotification*)noti
{
NSLog(@"%@",noti.userInfo);
// 1.取得当前聚焦文本框最下面的Y值
CGFloat Y =CGRectGetMaxY(_focusedField.frame);
NSLog(@"%f",Y);
// 2.取出键盘的高度(控制器的高度-键盘的高度)
CGFloat keyboardH = [noti.userInfo[UIKeyboardFrameBeginUserInfoKey]CGRectValue].size.height;
CGFloat keyboardY =self.view.frame.size.height- keyboardH;
// 3.比较文本框的大小
CGFloat duration = [noti.userInfo[UIKeyboardAnimationDurationUserInfoKey]floatValue];
[UIViewanimateWithDuration:durationanimations:^{
// 键盘遮住了文本框
if (keyboardY < Y) {
self.view.transform= CGAffineTransformMakeTranslation(0, keyboardY - Y - 10);
}else{
self.view.transform= CGAffineTransformIdentity;
}
}];
}
#pragma mark -监听键盘将要隐藏
- (void)keyboardWillHide:(NSNotification*)noti
{
// 时长
CGFloat duration = [noti.userInfo[UIKeyboardAnimationDurationUserInfoKey]floatValue];
// 设置动画,让键盘隐藏的时候按照时长隐藏
[UIViewanimateWithDuration:durationanimations:^{
// CGAffineTransformIdentity属性能还原到进行动画之前的状态
self.view.transform= CGAffineTransformIdentity;
}];
}
5.12移除监听通知
#pragma mark -监听器销毁之前取消注册
- (void)dealloc
{
[[NSNotificationCenterdefaultCenter]removeObserver:self];
}
// 3.获得所有的文本输入框
MJKeyboardTool *tool = [MJKeyboardTool keyboardTool];
tool.delegate = self;
for(UIView *child in self.view.subviews) {
// 如果是文本输入框,就设置工具条
if ([child isKindOfClass:[UITextField class]]) {
UITextField *field = (UITextField *)child;
field.inputAccessoryView = tool;
}
}
5.9判断工具条上的按钮是否能点击
#pragma mark - UITextField代理
#pragma mark - 开始点击文本框的时候调用
- (void)textFieldDidBeginEditing:(UITextField*)textField
{
_focusedField = textField;
int index = [_fieldsindexOfObject:_focusedField];
_keyboardTool.previousBtm.enabled= (index != 0);
_keyboardTool.nextBtm.enabled= (index != (_fields.count- 1));
}
5.10监听系统发出键盘滚动通知
#pragma mark -监听系统发出的通知
- (void)addkeyboard
{
NSNotificationCenter *center = [NSNotificationCenterdefaultCenter];
// 监听键盘将要显示
[center addObserver:selfselector:@selector(showKeyboard:)name:UIKeyboardWillShowNotificationobject:nil];
// 监听键盘将要隐藏
[center addObserver:selfselector:@selector(keyboardWillHide:)name:UIKeyboardWillHideNotificationobject:nil];
}
5.11当键盘挡住文本框将视图往上移
#pragma mark -监听键盘将要显示
- (void)showKeyboard:(NSNotification*)noti
{
NSLog(@"%@",noti.userInfo);
// 1.取得当前聚焦文本框最下面的Y值
CGFloat Y =CGRectGetMaxY(_focusedField.frame);
NSLog(@"%f",Y);
// 2.取出键盘的高度(控制器的高度-键盘的高度)
CGFloat keyboardH = [noti.userInfo[UIKeyboardFrameBeginUserInfoKey]CGRectValue].size.height;
CGFloat keyboardY =self.view.frame.size.height- keyboardH;
// 3.比较文本框的大小
CGFloat duration = [noti.userInfo[UIKeyboardAnimationDurationUserInfoKey]floatValue];
[UIViewanimateWithDuration:durationanimations:^{
// 键盘遮住了文本框
if (keyboardY < Y) {
self.view.transform= CGAffineTransformMakeTranslation(0, keyboardY - Y - 10);
}else{
self.view.transform= CGAffineTransformIdentity;
}
}];
}
#pragma mark -监听键盘将要隐藏
- (void)keyboardWillHide:(NSNotification*)noti
{
// 时长
CGFloat duration = [noti.userInfo[UIKeyboardAnimationDurationUserInfoKey]floatValue];
// 设置动画,让键盘隐藏的时候按照时长隐藏
[UIViewanimateWithDuration:durationanimations:^{
// CGAffineTransformIdentity属性能还原到进行动画之前的状态
self.view.transform= CGAffineTransformIdentity;
}];
}
5.12移除监听通知
#pragma mark -监听器销毁之前取消注册
- (void)dealloc
{
[[NSNotificationCenterdefaultCenter]removeObserver:self];
}
键盘处理例子思路
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。