我有一个UIView,它位于所有其他视图之上,并且重写了hitTest()方法,该方法总是返回自己:
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
return self
}然后,当我使用touchesBegan()中的点进行一些操作时,我需要将hitTest()传递给我们的UIView的下面的视图:
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()方法。然后,我需要处理触摸,执行一些操作,然后,如果需要,传递到下面的视图。有可能吗?
发布于 2018-02-10 04:58:43
以不同的方式解决你的问题可能更简单、更好。
UIKit通过将触摸事件发送到sendEvent(_:)消息中的窗口(视图层次结构的根)来传递触摸事件。窗口的sendEvent(_:)方法负责查找对触摸感兴趣的手势识别器,并向识别器和/或命中视图发送适当的touchesBegan、touchesMoved等消息。
这意味着您可以在事件到达任何手势识别器或视图之前,将UIWindow子类和重写sendEvent(_:)以查看窗口中的每个触摸事件,而无需重写任何视图的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)
}
}您可以在应用程序中使用这个窗口子类,方法是将应用程序委托的window出口初始化为它的一个实例,如下所示:
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow? = MyWindow()
// other app delegate members...
}注意,当触摸开始时,UIKit使用hitTest(_:with:)设置触摸的view属性,在之前,将触摸开始事件传递到窗口。UIKit还将每个触摸的gestureRecognizers属性设置为一组识别器,这些识别器可能需要触摸(识别器状态为.possible)或在将事件传递到窗口的sendEvent(_:)之前主动使用触摸(状态为began、changed、ended、cancelled)。因此,您的sendEvent(_:)覆盖可以查看每个触摸的view属性,如果它需要知道触摸的方向的话。
https://stackoverflow.com/questions/48715636
复制相似问题