问题描述
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)
}
}
}
目前在我们项目中已经通过这种方式全局兼容,如果有不妥之处,欢迎大家讨论!