前言
最近遇到一个键盘无法收起的问题,其实在这个项目期初就遇到了 ,因为现在开发的项目是类似于钉钉的办公类工具软件,其中涉及到各种文本输入,各种文本框选择事件,其中就遇到了键盘无法收起的问题,本来键盘收起是一个很简单的功能,只需要调用一下就可以了,大概这些方法,但是都无济于事。
[textField resignFirstResponder];
[self transformIdentityWith:self.view];
[self.view endEditing:YES];
[QCKeyWindow endEditing:YES];
问题复现及分析
像一个提交页面,多个文本框,多种事件,例如点击文本框展示 UIPickerView 、UIDatePicker 以及跳转点击地图选点及其它页面等功能。
问题来了:
在本页面中正在输入内容或选择日期等时,然后不要收起键盘,直接点击跳转页面的文本框,类似如下:
// 起始点
self.carInfoView.startTF.textDidBeginBlock = ^{
// [self.carInfoView.startTF becomeFirstResponder];
// [self.carInfoView.startTF resignFirstResponder];
MapChoosePointVC *chooseVC = [[MapChoosePointVC alloc] init];
chooseVC.responder = self.carInfoView.startTF;
chooseVC.selectPoiBlock = ^(AMapPOI *POI) {
// 获取位置信息
weakSelf.carInfoView.startTF.text = POI.name;
weakSelf.carInfoView.oLatitude = [NSString stringWithFormat:@"%f",POI.location.latitude];
weakSelf.carInfoView.oLongitude = [NSString stringWithFormat:@"%f",POI.location.longitude];
weakSelf.carInfoView.originAddress = POI.name;
};
[self.navigationController pushViewController:chooseVC animated:YES];
};
点击事件是在点击文本框时触发的,这时如果不处理的话,当前的文本框自然会成为第一响应者,但是从下个页面回来的时候会不停进入下个页面,回来时这个文本框依然处于第一响应者,所以会不停进入下个页面。
如果在点击进入下个页面的时候,调用 resignFirstResponder 放弃第一响应者的话,依然会有键盘无法收起的问题,放弃了当前文本框响应者,但是上一个文本框的键盘依然还在,开始试着在 UITextFieldDelegate 方法中处理:
#pragma mark -- UITextFieldDelegate
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
[textField resignFirstResponder];
[self transformIdentityWith:self.view];
[self.view endEditing:YES];
[QCKeyWindow endEditing:YES];
if (textField == _baseView.typeTF) {
[IQKeyboardManager sharedManager].enable = NO;
[textField resignFirstResponder];
[SinglePickerView showWithDataArray:dataArr block:^(NSString * _Nonnull selectStr, NSInteger index) {
//
textField.text = selectStr;
}];
}
[IQKeyboardManager sharedManager].enable = YES;
}
这样也是都无济于事,这种方法是针对当前文本框的。
解决方法
期间想到另外一种方法就是不用文本框,使用 按钮,添加事件,也是一种方法,但是没采用。
其实在上面分析的时候已经看出来了,这是一个响应者的问题,所以在点击的时候,先不要放弃第一响应者,将当前响应者传至下个页面:
/** 点击进来的相应者 */
@property (strong, nonatomic) UIResponder *responder;
chooseVC.responder = self.carInfoView.startTF;
然后在下个页面的 viewDidLoad 方法中
- (void)viewDidLoad {
[super viewDidLoad];
// 在这里放弃响应者
[self.responder resignFirstResponder];
}
至此,就解决了键盘无法收起的问题,返回也正常了,算不上完美吧!
另附:iOS 之UIResponder 类
在iOS中UIResponder类是专门用来响应用户的操作处理各种事件的,包括触摸事件(Touch Events)、运动事件(Motion Events)、远程控制事件(Remote Control Events,如插入耳机调节音量触发的事件)。
我们知道UIApplication、UIView、UIViewController这几个类是直接继承自UIResponder,UIWindow是直接继承自UIView的一个特殊的View,所以这些类都可以响应事件。当然我们自定义的继承自UIView的View以及自定义的继承自UIViewController的控制器都可以响应事件。iOS里面通常将这些能响应事件的对象称之为响应者。
使用方法可以查看 UIResponder 这个类的 API。
网友评论