iOS14 UITableViewCell 问题

问题描述

Xcode12目前没有发布正式版本,但是通过Xcode-Beta版本测试发现,项目中好多 UITableViewCell的子试图不能点击或者滑动等手势响应问题。

通过排查发现这部分有问题的Cell基本都是直接 cell.addSubView(tempView1)这种方式添加的,通过试图查看发现被系统自带的 cell.contentView` (类名UITableViewCellContentView)遮挡在底部了,所以需要改为 '''cell.contentView.addSubView(tempView1)

搜了一下项目中有 200多处的位置都是这么写的,而且分很多不同的组件,兼容工作量很大。

所以通过Runtime简单暴力的方式快速兼容了,原理就是在所有Cell addSubView()时,通过runtime拦截改为 contentView.addsubview(),Demo代码如下:
extension UITableViewCell {
    
    class func ios14Bug() {
        
        let sel1 = #selector(UITableViewCell.runtime_addSubview(_:))
        let sel2 = #selector(UITableViewCell.addSubview(_:))
        
        let method1 = class_getInstanceMethod(UITableViewCell.self, sel1)!
        let method2 = class_getInstanceMethod(UITableViewCell.self, sel2)!
        
        let isDid: Bool = class_addMethod(self, sel2, method_getImplementation(method1), method_getTypeEncoding(method1))
        if isDid {
            class_replaceMethod(self, sel1, method_getImplementation(method2), method_getTypeEncoding(method2))
        } else {
            method_exchangeImplementations(method2, method1)
        }
    }
    
    @objc func runtime_addSubview(_ view: UIView) {
        // 判断不让 UITableViewCellContentView addSubView自己
       // 还需要注意 屏蔽掉一些系统直接添加在Cell上的控件,如 UITableViewCellEditControl、UITableViewCellReorderControl
        if view.isKind(of: NSClassFromString("UITableViewCellContentView")!) ||
           view.isKind(of: NSClassFromString("UITableViewCellEditControl")!) ||
           view.isKind(of: NSClassFromString("UITableViewCellReorderControl")!) {
            runtime_addSubview(view)
        } else {
            self.contentView.addSubview(view)
        }
    }
}

目前在我们项目中已经通过这种方式全局兼容,如果有不妥之处,欢迎大家讨论!

推荐阅读更多精彩内容