核心方法
在 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。
示例代码
区别总结
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