如何让点击穿透UITableView触发后方UIButton?
解决透明UITableView触摸穿透、滚动与按钮响应共存问题
核心思路
通过重写UITableView的hitTest(_:with:)方法精准控制触摸事件流向:
- 保留滚动功能:不关闭
userInteractionEnabled,滚动视图的手势识别逻辑不受影响 - 保障单元格按钮响应:命中可交互控件时,正常返回该控件作为事件响应者
- 实现空白区域穿透:命中非交互区域时,返回nil让事件继续向下传递给后方视图
自定义UITableView子类实现
class PassThroughTableView: UITableView { override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { let hitView = super.hitTest(point, with: event) guard let targetView = hitView else { return nil } // 点击表格自身空白区域,直接返回nil让事件穿透 if targetView === self { return nil } // 仅保留可交互控件/带手势视图的事件响应权 let isInteractiveControl = targetView is UIControl let hasValidGestures = !targetView.gestureRecognizers.isEmpty if isInteractiveControl || hasValidGestures { return targetView } // 非交互区域(如单元格空白contentView),事件穿透 return nil } }
使用说明
- 将项目中原有的
UITableView替换为PassThroughTableView(代码或Storyboard中修改类名均可) - 确保表格后方的
UIButton开启userInteractionEnabled,且无其他遮挡视图 - 单元格内的按钮、带手势的自定义视图无需额外修改,会自动响应点击
- 表格的滚动、下拉刷新等原有功能完全保留
关键逻辑解释
hitTest是iOS触摸事件传递的核心入口,负责返回当前触摸点的最佳响应视图- 触摸表格空白区域时返回nil,系统会将事件继续传递给表格下方的视图,触发后方按钮点击
- 触摸到可交互控件(如UIButton)或带手势的视图时返回该视图,保证其正常响应触摸事件
- 滚动视图的手势识别基于触摸序列跟踪,不受
hitTest返回nil的影响,滚动功能完全正常
内容的提问来源于stack exchange,提问作者Fattie
相关产品推荐
相关产品推荐

