学学人家的框架上海恩美路演程序员

IQKeyboardManager遇到UIView的坑

2017-09-11  本文已影响151人  蝴蝶之梦天使
坑,大坑

IQKeyboardManager很好用。
IQKeyboardManager继承简单。
IQKeyboardManager持续更新。

踩坑

最新很偶然的机会了解到IQKeyboardManager第三方库,感觉从各方面比较,都比我现在使用的TPKeyboardAvoiding好。所以果断的替换。整个APP测试了一边,感觉不错,完全符合要求。直到5小时前,我开始编写一个UITableView的UITableViewCell中嵌套UITextView,进行调试时,出现了崩溃的现象。

SectionHeader

可以从图中看到,Section header view 好像没有受到UITableView的改变而改变,一直停留在原来的位置。什么鬼啊,直接无语。开始怀疑IQKeyboardManager没有支持这样的场景。下载Demo并在Demo修改UITableView的样例,发现并不存在问题。

原因

应该还是我的代码的问题,开始筛选原因吧。

UITableViewWrapperView
在查看UI界面时,发现了一个奇怪的现象,UITableViewWrapperView为何在键盘弹出后没有改变。这个应该是问题所在。
但是面对上千个文件,怎么进行查找啊。这个时候才现在组件化真的是很有好处,直接按组件进行排查。_
最后将问题定位在UIViewExtensions.h中,删除这个文件后,问题被修复了。

解决

发现原来UIViewExtensions类中的方法

- (UIView*) superviewOfClassType: (Class) classType
{
    UIView* view = self.superview;
    
    while (view != nil)
    {
        if ([view isKindOfClass: classType])
        {
            return view;
        }
        
        view = view.superview;
    }
    
    return nil;
}

与IQKeyboardManager库中IQUIView+Hierarchy类重名了,也就是所说的覆盖了。

-(UIView*)superviewOfClassType:(Class)classType
{
    UIView *superview = self.superview;
    
    while (superview)
    {
        if ([superview isKindOfClass:classType])
        {
            //If it's UIScrollView, then validating for special cases
            if ([superview isKindOfClass:[UIScrollView class]])
            {
                NSString *classNameString = NSStringFromClass([superview class]);

                //  If it's not UITableViewWrapperView class, this is internal class which is actually manage in UITableview. The speciality of this class is that it's superview is UITableView.
                //  If it's not UITableViewCellScrollView class, this is internal class which is actually manage in UITableviewCell. The speciality of this class is that it's superview is UITableViewCell.
                //If it's not _UIQueuingScrollView class, actually we validate for _ prefix which usually used by Apple internal classes
                if ([superview.superview isKindOfClass:[UITableView class]] == NO &&
                    [superview.superview isKindOfClass:[UITableViewCell class]] == NO &&
                    [classNameString hasPrefix:@"_"] == NO)
                {
                    return superview;
                }
            }
            else
            {
                return superview;
            }
        }
        
        superview = superview.superview;
    }
    
    return nil;
}

其实分类的方法重名并不存在覆盖的问题,只是在编译的时候谁的方法在前,那么谁的方法将会被执行。

修改UIViewExtensions类中的方法后,显示正常。


正常喽

查看键盘弹出的UI界面可以清楚的看到,UITableViewWrapperView在键盘弹出后向上缩进,避免键盘所在的部分被覆盖。

UITableViewWrapperView正常

还是希望IQKeyboardManager能够模仿AFNetworking或SDWebImage使用自己的前缀,避免这样的问题再次出现。

// END

上一篇下一篇

猜你喜欢

热点阅读