我有一个 UIView,它位于所有其他 View 之上,并且覆盖了始终返回自身的 hitTest() 方法:
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
return self
}
然后,当我使用来自 touchesBegan() 的点进行一些操作时,我需要将 hitTest() 传递给我们的 UIView 下面的 View :
override public func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
// Do some operations
// ...
// ...
// ...
// pass touch event handling to views below or change hitTest()
}
基本上,在顶部的 UIView 上,我覆盖了 touchesBegan()、touchesMoved() 和 touchesEnded() 方法。然后我需要处理触摸,执行一些操作,然后,如果需要,传递给下面的 View 。可能吗?
最佳答案
以不同的方式解决您的问题可能更简单、更好。
UIKit 通过在 sendEvent(_:)
消息中将触摸事件发送到窗口( View 层次结构的根)来传递触摸事件。窗口的 sendEvent(_:)
方法负责找到对触摸感兴趣的手势识别器,并发送适当的 touchesBegan
、touchesMoved
等. 给识别器和/或命中 View 的消息。
这意味着您可以子类化 UIWindow
并覆盖 sendEvent(_:)
以在事件到达任何手势识别器之前查看窗口中的每个触摸事件或 View ,而不覆盖任何 View 的 hitTest(_:with:)
方法。然后将事件传递给 super.sendEvent(event)
以进行正常路由。
例子:
class MyWindow: UIWindow {
override func sendEvent(_ event: UIEvent) {
if event.type == .touches {
if let count = event.allTouches?.filter({ $0.phase == .began }).count, count > 0 {
print("window found \(count) touches began")
}
if let count = event.allTouches?.filter({ $0.phase == .moved }).count, count > 0 {
print("window found \(count) touches moved")
}
if let count = event.allTouches?.filter({ $0.phase == .ended }).count, count > 0 {
print("window found \(count) touches ended")
}
if let count = event.allTouches?.filter({ $0.phase == .cancelled }).count, count > 0 {
print("window found \(count) touches cancelled")
}
}
super.sendEvent(event)
}
}
您可以通过将应用委托(delegate)的 window
导出初始化为其实例,在您的应用中使用此窗口子类,如下所示:
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow? = MyWindow()
// other app delegate members...
}
请注意,当触摸开始时,UIKit 使用 hitTest(_:with:)
设置触摸的 view
属性,之前将触摸开始事件传递给窗口。 UIKit 还将每个触摸的 gestureRecognizers
属性设置为一组可能需要触摸的识别器(识别器状态 .possible
)或正在积极使用触摸(状态 began
, changed
, ended
, cancelled
) 在将事件传递给窗口的 sendEvent(_:)
之前.因此,您的 sendEvent(_:)
覆盖可以查看每个触摸的 view
属性,如果它需要知道触摸的去向。
关于ios - 在 touchesMoved 中调用 hitTest,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48715636/