登录界面-[UIKBBlurredKeyView candidateList]: unrecognized selector sent to instance 0x11c464bf0
从崩溃日志中定位到了这个错误才发现之前从没发现过的bug
崩溃日志定位错误详见 iOS查看线上App崩溃信息及第三方Crash监控
上图是很常见的一个登录场景,在一个视图中放入几个UITextField,当输入框过多或者屏幕尺寸较小时候就需要放在UIScorllView中。当点击其他空白处时候需要隐藏键盘。
通常的解决场景很简单,网络上搜集到的资料也大同小异。
@implementation UIScrollView (UITouch)
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[[self nextResponder] touchesBegan:touches withEvent:event];
[super touchesBegan:touches withEvent:event];
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
[[self nextResponder] touchesMoved:touches withEvent:event];
[super touchesMoved:touches withEvent:event];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[[self nextResponder] touchesEnded:touches withEvent:event];
[super touchesEnded:touches withEvent:event];
}
@end
这个做法是写一个UIScrollView的分类,把Touch事件向后传递。在UITextField所在的界面中重写touchesBegan和touchesMoved
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
[super touchesBegan:touches withEvent:event];
[self.textField resignFirstResponder];
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesMoved:touches withEvent:event];
[self.textField resignFirstResponder];
}
之前这么写一直没问题,直到上次出现那个崩溃信息。
这个错误是在打开中文手写键盘时候出现的。之前没发现是因为很少人会用到这个键盘。
当打开手写键盘,随便写一个字,键盘上面会跟出这个文字的联想文字。点击以后上方的联想区域就会变成一个半透明的View。再点击就崩溃。
现在可以肯定是因为在UISCrollview的扩展中重新Touch事件导致的。因为键盘的联想区域也是UIScorllView,向下传递时候出现了问题。
这个bug的解决思路有很多。如果还想用上面那一套,可以删掉UIScrollview的扩展。写一个UIScrollview的子类,在子类中重写Touch事件。然后把当前的UIScrollview继承那个子类。这样就不会对所有的UIScrollView都有影响了。
也可以加一个Tap事件在当前View上
/**
* 收回键盘事件
*/
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(keyboardHide:)];
//设置成NO表示当前控件响应后会传播到其他控件上,默认为YES。
tapGestureRecognizer.cancelsTouchesInView = NO;
//将触摸事件添加到当前view
[self.view addGestureRecognizer:tapGestureRecognizer];
当想滚动ScrollView时候也行隐藏键盘,可以当前类实现UIScrollViewDelegate
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
if (self.emailTextField.isFirstResponder) {
[self.emailTextField resignFirstResponder];
}
if (self.passWordTextField.isFirstResponder) {
[self.passWordTextField resignFirstResponder];
}
}
当然还有其他办法。就不一一叙述了。
以上。
网友评论