在 iOS14中,UITableViewCell 中直接添加在 cell 上的控件,也就是通过 [self addSubview:]的 方式添加控件,会显示在 contentView 的下层。
contentView 会阻挡事件交互,使所有事件都响应 tableView:didSelectRowAtIndexPath:方法,如果 customView 存在交互事件将无法响应。如果 contentView 设置了背景色,还会影响界面显示。
关于 contentView 的声明注释中,官方已经明确建议开发者将 customView 放在 contentView 上,使 contentView 作为 UITableViewCell 默认的 superView。
项目中很多地方都是直接通过 [self addSubview:]实现的,如果每处都修改工作量比较大,通过runtime的方式快速兼容。
解决方法
新建一个UITableViewCell的分类,添加以下代码
+ (void)load {
SEL sel1 = @selector(runtime_addSubview:);
SEL sel2 = @selector(addSubview:);
// 获取自己定义的对象方法
Method runtime_addSubviewMethod = class_getInstanceMethod(self, sel1);
// 获取系统的对象方法
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];
}
}
网友评论