在 iOS14中,UITableViewCell 中直接添加在 cell 上的控件,也就是通過(guò) [self addSubview:]的 方式添加控件,會(huì)顯示在 contentView 的下層。
contentView 會(huì)阻擋事件交互,使所有事件都響應(yīng) tableView:didSelectRowAtIndexPath:方法,如果 customView 存在交互事件將無(wú)法響應(yīng)。如果 contentView 設(shè)置了背景色,還會(huì)影響界面顯示。
關(guān)于 contentView 的聲明注釋中,官方已經(jīng)明確建議開發(fā)者將 customView 放在 contentView 上,使 contentView 作為 UITableViewCell 默認(rèn)的 superView。
項(xiàng)目中很多地方都是直接通過(guò) [self addSubview:]實(shí)現(xiàn)的,如果每處都修改工作量比較大,通過(guò)runtime的方式快速兼容。
解決方法
新建一個(gè)UITableViewCell的分類,添加以下代碼
+ (void)load {
SEL sel1 = @selector(runtime_addSubview:);
SEL sel2 = @selector(addSubview:);
// 獲取自己定義的對(duì)象方法
Method runtime_addSubviewMethod = class_getInstanceMethod(self, sel1);
// 獲取系統(tǒng)的對(duì)象方法
Method addSubviewMethod = class_getInstanceMethod(self, sel2);
BOOL isDid = class_addMethod(self, sel2, method_getImplementation(runtime_addSubviewMethod), method_getTypeEncoding(runtime_addSubviewMethod));
if (isDid) {
class_replaceMethod(self, sel1, method_getImplementation(addSubviewMethod), method_getTypeEncoding(addSubviewMethod));
} else {
// 方法交換
method_exchangeImplementations(addSubviewMethod, runtime_addSubviewMethod);
}
}
- (void)runtime_addSubview:(UIView *)view {
// 判斷不讓 UITableViewCellContentView addSubView自己
if ([view isKindOfClass:NSClassFromString(@"UITableViewCellContentView")]) {
[super addSubview:view];
} else {
[self.contentView addSubview:view];
}
}