求助:Xcode12中嵌套UITableViewCell内的TableView点击异常问题
解决Xcode12升级后嵌套TableView交互异常问题
我之前在Xcode版本升级时也踩过类似的嵌套TableView交互冲突的坑,结合你的描述,给你几个亲测有效的解决方案:
1. 重写父TableView的hitTest方法,让子视图优先响应触摸
Xcode12对应的iOS14 SDK调整了UITableView的触摸事件处理逻辑,父TableView的内置手势很可能会拦截子TableView的触摸动作。你可以自定义父TableView,重写hitTest(_:with:)方法,确保触摸点落在子TableView范围内时,优先交给子TableView处理:
class ParentTableView: UITableView { override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { let originalHitView = super.hitTest(point, with: event) // 判断触摸目标是否属于子TableView或其子视图 func isSubTableViewRelated(view: UIView?) -> Bool { guard let currentView = view else { return false } if currentView is UITableView { return true } return isSubTableViewRelated(view: currentView.superview) } if isSubTableViewRelated(view: originalHitView) { // 将触摸点转换到子TableView坐标系,让子视图处理事件 if let subTableView = originalHitView as? UITableView ?? originalHitView.superview as? UITableView { let convertedPoint = convert(point, to: subTableView) return subTableView.hitTest(convertedPoint, with: event) } } return originalHitView } }
2. 检查所有交互元素的userInteractionEnabled状态
升级后部分控件的交互属性可能被默认重置,务必逐一确认:
- 子TableView的
isUserInteractionEnabled = true - 子TableView单元格的
isUserInteractionEnabled = true - 图片控件(UIImageView)的
isUserInteractionEnabled = true(UIImageView默认关闭交互,之前能点击肯定手动开启过,升级后可能被意外覆盖)
3. 处理手势识别器的冲突
父TableView的内置手势可能和子视图的手势发生冲突,你可以给父TableView的手势添加代理,精准控制手势的触发逻辑:
class YourParentViewController: UIViewController, UIGestureRecognizerDelegate { @IBOutlet weak var parentTableView: UITableView! override func viewDidLoad() { super.viewDidLoad() // 给父TableView的所有手势设置代理 parentTableView.gestureRecognizers?.forEach { $0.delegate = self } } // 允许子TableView的手势与父手势同时触发 func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool { return otherGestureRecognizer.view is UITableView } // 当触摸点在子TableView范围内时,阻止父手势触发 func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool { let touchPoint = gestureRecognizer.location(in: view) // 遍历所有可见父单元格,判断触摸点是否在子TableView区域内 for cell in parentTableView.visibleCells { guard let parentCell = cell as? ParentTableViewCell else { continue } let subTableViewFrame = parentCell.convert(parentCell.subTableView.frame, to: view) if subTableViewFrame.contains(touchPoint) { return false } } return true } }
4. 确认子TableView的选择权限
不要忽略最基础的设置:确保子TableView的allowsSelection = true,如果这个属性被设为false,单元格肯定无法选中。
建议先从检查基础交互属性开始,再尝试手势或hitTest的方案,一般就能解决问题了。
内容的提问来源于stack exchange,提问作者Manish
相关产品推荐
相关产品推荐

