这些天项目中碰到一个恶心的bug是关于系统键盘的。因为这个项目为混编,所以在光标获取和键盘调用的时候就会特别有“喜感”(bug)。此前,我只是依稀感觉苹果的原生键盘我们是没有多大的操作权限的,接触最多的也就是键盘出现和消失的那几个通知。然而这次我碰到一个硬菜,苹果九宫格键盘坍塌,华丽丽的在我的眼皮子底下塌了,难死我了。现在总结下系统键盘它的来世今生。
1.系统键盘实际是添加在一个window上的。 我们将view是添加在window上的,然而我们平时使用的系统键盘它是单独存在于一个新的window上的。多说一点,别看可以有好多window(如键盘,警示框)但是在一个时刻App中只能主window只有一个。主window存在于响应者链中,系统提供了通知供我们拿到主window的变化。 UIWindowDidBecomeKeyNotification 变为主window的通知 UIWindowDidResignKeyNotification 取消主window的通知 2.键盘的简单分解 寻找键盘思路为打印出系统window列表取到对应的键盘window,再遍历出子视图(打印键盘和其子视图的时候,层级是比较多的)。 一般我们经常使用的键盘如英文输入或者九宫格输入,它整个键盘分为两大部分(内部有没有细分,没有继续向下追)。拿九宫格来说,所有的点击19个相应按钮(代表a-z以及删除和各功能的一个个按钮们)在一个view承载,这个view名字叫做keyboardLayoutStar。其上部就是我们使用拼音拼出来的汉字显示栏和我们点击的对应字母显示栏,此两个在一个view上,view叫做_UIInputViewContent。3.代码
注意一点,我在调整键盘位置到正确的位置的时候,只有同时设置view的frame和layer.frame更改才生效,在此希望研究出原因的大神能点化下。(我自己的困惑:在学习的时候关于frame的设置归根到底也就是设置layer的为什么此处出现这样的问题,还是我的理解本来就是错的,希望知晓谜底的大神看到后在笑话完我之后能给答疑下,感之不尽)
- (UIView *)fixKeyboard { for (UIWindow* window in [UIApplication sharedApplication].windows) { UIView *inputSetContainer = [self viewWithPrefix:@"<UIInputSetContainerView:" fromView:window]; if (inputSetContainer) { UIView *inputSetHost = [self viewWithPrefix:@"<UIInputSetHostView:" fromView:inputSetContainer]; if (inputSetHost) { UIView *kbinputbackdrop = [self viewWithPrefix:@"<_UIKBCompatInputView:" fromView:inputSetHost]; if (kbinputbackdrop) { //系统键盘 UIView *keyboard = [self viewWithPrefix:@"<UIKeyboardAutomatic" fromView:kbinputbackdrop]; CGRect rect; // NSLog(@"keyboard--%@",keyboard); for (UIView *view in keyboard.subviews) { UIView *keyboardLayoutStar = [self viewWithPrefix:@"<UIKeyboardLayoutStar:" fromView:view]; if (keyboardLayoutStar) { rect = keyboardLayoutStar.frame; // NSLog(@"keyboardLayoutStar--%@",keyboardLayoutStar);//调整键盘上的布局
} } } return keyboard; } } } } return nil; }//寻找键盘
- (UIView *)viewWithPrefix:(NSString *)prefix fromView:(UIView *)view { for (UIView *subview in view.subviews) { // NSLog(@"subview====%@",subview); if ([[subview description] hasPrefix:prefix]) { return subview; } } return nil; }