核心方法
在 iOS 中,hitTest(_:with:)
和 point(inside:with:)
是处理触摸事件传递的两个关键方法。它们经常一起使用,但有不同的作用和工作原理。以下是它们的详细解释和区别:
1. hitTest(_:with:)
hitTest(_:with:)
作用
hitTest(_:with:)
是用来确定哪个视图应该响应触摸事件的。它会在视图层次结构中进行递归查找,最终找到最合适的视图来处理事件。
工作原理
当用户触摸屏幕时,系统从视图的最顶层(如
UIWindow
)开始调用hitTest(_:with:)
,遍历每个子视图来找到最合适的视图。通过
hitTest(_:with:)
,系统可以确定触摸事件的目标视图,并将事件交给该视图处理。
执行过程
调用
point(inside:with:)
方法来确定触摸点是否在当前视图内。如果触摸点在当前视图内,则递归检查所有子视图,找到最靠近触摸点的、可以响应事件的子视图。
最后返回能够处理事件的视图。
示例代码
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
if !self.isUserInteractionEnabled || self.isHidden || self.alpha < 0.01 {
return nil
}
if self.point(inside: point, with: event) {
for subview in self.subviews.reversed() {
let convertedPoint = subview.convert(point, from: self)
if let hitView = subview.hitTest(convertedPoint, with: event) {
return hitView
}
}
return self
}
return nil
}
在这个例子中,hitTest(_:with:)
会检查每个子视图,并根据视图是否能处理事件返回适当的视图。
2. point(inside:with:)
point(inside:with:)
作用
point(inside:with:)
方法用于判断一个触摸点是否位于当前视图的边界内。它只检查给定的点是否在当前视图的范围中,不做其他任何事件处理。
工作原理
point(inside:with:)
方法的返回值是一个布尔值。如果触摸点在当前视图的边界内,它返回true
,否则返回false
。该方法通常在
hitTest(_:with:)
内部被调用,用于辅助确定触摸事件的目标视图。
执行过程
检查触摸点是否在当前视图的范围内。视图的范围通常由视图的
bounds
属性决定。如果点在范围内,返回
true
,否则返回false
。
示例代码
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
let isInside = self.bounds.contains(point)
return isInside
}
区别总结
hitTest(_:with:)
:用来确定触摸事件的目标视图。
它在视图层次结构中递归查找,最终返回能够处理事件的视图。
hitTest(_:with:)
调用point(inside:with:)
来帮助判断点是否在视图内。
point(inside:with:)
:用来判断触摸点是否在当前视图的范围内。
只做简单的几何判断,返回一个布尔值。
这个方法通常在
hitTest(_:with:)
中被调用,不会单独用于事件传递的最终决策。
hitTest(_:with:)
和 point(inside:with:)
的关系
hitTest(_:with:)
和 point(inside:with:)
的关系hitTest(_:with:)
是触摸事件传递的主入口方法,它依赖point(inside:with:)
来判断触摸点是否在视图范围内。当一个视图接收到触摸事件时,首先会调用
point(inside:with:)
来判断事件是否发生在视图内。如果返回true
,则hitTest(_:with:)
继续检查子视图;否则直接返回nil
。
应用场景
hitTest(_:with:)
主要用于自定义事件传递行为。例如,如果你希望事件传递给视图之外的区域,或者希望在特定条件下阻止事件传递,可以重写hitTest(_:with:)
。point(inside:with:)
通常用于改变视图的点击区域。例如,你可以通过重写这个方法来扩大或缩小视图的点击区域。
总结
hitTest(_:with:)
用于确定哪个视图响应触摸事件,依赖point(inside:with:)
判断触摸点是否在视图的边界内。point(inside:with:)
是一个辅助方法,它只做几何判断,并不决定事件传递逻辑。
Last updated