如何在自定义UIView子类中实现仅响应条形区域的触摸检测?
解决自定义UIView仅响应绘制图形内部触摸的问题
核心问题分析
你当前的hitTest写法存在逻辑错误:当触摸不在条形区域时返回superview,系统会判定触摸已被父视图处理,不会继续向下遍历其他BarView子视图。正确的做法是让不处理触摸的BarView返回nil,这样系统会自动检查下层的兄弟视图。
两种可行解决方案
方案1:重写point(inside:with:)(推荐,更简洁)
系统通过这个方法判断触摸点是否属于当前视图,默认逻辑是检查点是否在视图frame内。我们可以重写它,仅当触摸点落在条形矩形内时返回true:
class BarView: UIView { // 存储你绘制的条形的矩形区域 var barRect: CGRect = .zero override func point(inside point: CGPoint, with event: UIEvent?) -> Bool { // 仅当触摸点在条形范围内时,才认为属于当前视图 return barRect.contains(point) } }
这样系统的默认hitTest逻辑会自动跳过不在条形内的触摸,转而检查下层的BarView。
方案2:正确重写hitTest(_:with:)
如果你需要更复杂的触摸判断逻辑,可以重写hitTest,注意在不处理触摸时返回nil:
class BarView: UIView { var barRect: CGRect = .zero override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { // 先检查当前视图是否具备接收触摸的条件 guard isUserInteractionEnabled, !isHidden, alpha >= 0.01 else { return nil } // 判断触摸点是否在条形区域内 if barRect.contains(point) { return self } // 不处理该触摸,返回nil让系统继续查找其他视图 return nil } }
关键注意事项
- 确保所有
BarView的isUserInteractionEnabled都设为true - 条形矩形
barRect的坐标系要和BarView的本地坐标系一致(绘制时使用本地坐标的话,直接用即可)
内容的提问来源于stack exchange,提问作者Andrei Herford
相关产品推荐
相关产品推荐

