问题描述
系统要求:iOS 11.2及之前版本
设备要求:无
问题详情:因为需要适配小屏幕设备,多个输入框的时候可能需要放在UIScorllView中。当点击其他空白处时候需要隐藏键盘。方法有很多,其中一种做法就是写一个UIScrollView的分类,把Touch事件向后传递,在UITextField所在的界面中重写Touch事件方法关闭键盘。
@implementation UIScrollView (Touch)
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[[self nextResponder] touchesBegan:touches withEvent:event];
[super touchesBegan:touches withEvent:event];
}
@end
然后用手写输入法写了一个字后,候选词的位置变灰色,一点就崩溃。
崩溃日志
问题关键信息:
-[UIKBBlurredKeyView candidateList]: unrecognized selector sent to instance
原因分析
点击手写板的候选词区域(UIKBCandidateCollectionView
)时,同样执行了上面的代码,然后事件响应向上传递,但这个view的nextResponder
是UIKBHandwritingCandidateView
类的实例。执行它的touchesBegan:withEvent:
方法后,会使得整个候选词区域呈选中状态,本应调用UIKBCandidateView
实例的方法candidateList
,结果调用了UIKBBlurredKeyView
的candidateList方法
,导致方法找不到,导致-[UIKBBlurredKeyView candidateList]: unrecognized selector sent to instance
的崩溃。
解决方案
- 方案一:
在touchesBegan
方法里对不同的类进行类型判断,只对UIScrollView做响应:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
if ([self isMemberOfClass:[UIScrollView class]]) {
[[self nextResponder] touchesBegan:touches withEvent:event];
}
[super touchesBegan:touches withEvent:event];
}
- 方案二:
使用UITapGestureRecognizer
类,进行用户的点击事件拦截,且要将tap的cancelsTouchesInView
属性设置为NO
,否则会屏蔽到当前view的点击事件。