代码改变世界

iOS奇怪的问题,键盘偏移异常

2017-03-20 13:44  Hi,David  阅读(2019)  评论(0编辑  收藏  举报

现象描述:

点击UITextView,键盘会弹出。然后点击添加图片,弹出了ActionSheet,键盘自动收缩。接着关闭ActionSheet,发现键盘又弹出了,接着点击Done,想要隐藏键盘,却发现视图出现移动异常。项目中已集成IQKeyboardManager框架。

现象截图:

原因假设:

1.一开始点击UITextView,UITextView获得焦点,键盘正常弹出。此时如果不点击添加图片,直接点击Done是没有异常出现的,在我点击添加图片的时候,系统默认关闭键盘,然后弹出ActionSheet,在我关闭ActionSheet之后,系统为了恢复到弹出ActionSheet之前的状态,就又调出了键盘,此时点击Done,由于IQKeyboardManager可能会记录键盘的Offset,所以点击Done的时候移动了VC的frame。

 

查看问题后的VC的Frame的:

 

经过仔细排查,发现上面的Frame和ActionSheet的Frame是类似的,初步确定IQKeyboardManager在获取VC的时候,把RootVC回溯到ActionSheet上去了,这。。。

 

后来又打断点调试,发现执行到634行的时候代码获取到了错误的Frame,然后,我就进一步确定是获取到了ActionSheet的Frame。

然后我按住command点击topMostController,看看里面到底是怎么实现的。

附上解决后的代码:

- (UIViewController*) topMostController
{
    UIViewController *topController = [self rootViewController];
    
    //  Getting topMost ViewController
    /**  //原始代码
    while ([topController presentedViewController]){
        topController = [topController presentedViewController];
    }
    */
    
    //修改后的代码
    while ([topController presentedViewController]){
        UIViewController *vc = [topController presentedViewController];
        if (CGSizeEqualToSize(vc.view.frame.size, [[UIScreen mainScreen] bounds].size)) {
            topController = vc;
        }else{
            break;
        }
    }
    
    
    //  Returning topMost ViewController
    return topController;
}

原始代码是框架中原本的代码,修改后的代码是我自己添加的代码,修改过后,代码就没有问题了哦,哈哈,感谢这篇博客,我在写博客的过程中把思路理顺了,才无意中发现了解决办法,以后碰到问题,也应该理顺思路,一步步分析。最后附上解决后的截图。

 

最后说明一下,RootVC最后的Frame和ActionSheet的Frame为何只有x、y相同,而Width和Height的不相同。原因见下面的截图:

这个方法会在UIKeyboardWillHideNotification发出之后执行,由于我的系统是iOS 10的,所以这个Frame的Size会在这里修改。而需要注意的是在修改Size之前,这里也回溯了一遍RootVC,难道此处回溯的VC就不会回溯到ActionSheet吗?理论上是不会的。

因为IQKeyboardManager的目的就是:在键盘弹出之前记录下RootVC的Frame,然后上移视图,然后在键盘消失的时候重新还原RootVC的Frame,因此2次获取的RootVC必须是同一个对象,但是如果获取的是不一样的对象就会出现视图偏移异常。而ActionSheet和Alert都是由UIAlertViewController来控制,因此理论上这两种场景下都会出现视图偏移的问题。