ios - 在 touchesMoved 中调用 hitTest

标签 ios swift uiview

我有一个 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(_:) 方法负责找到对触摸感兴趣的手势识别器,并发送适当的 touchesBegantouchesMoved 等. 给识别器和/或命中 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/

相关文章:

swift - 使用NSTimer按设定的时间间隔播放声音,在后台不工作Xcode6.4

ios - UIView insertSubview atIndex 移动 subview 奇怪的行为

ios - 如何在 OpenGL ES 2.0 中使用可分离滤镜着色器?

ios - 我可以声明应用范围内的首字母缩写词替代画外音吗?

ios - 在 IOS 中以编程方式安装企业应用程序

ios - 如何在 Swift 中单击 TextField 外部时隐藏 TextField 中的 TEXT?

android - android sherlock actionbar 与 iOS 中的 UINavigationBar 相同吗?

swift - 如何将一个 pickerview 用于多个文本字段?

iphone - iOS:UIView 相对于 UIWindow 的起源

uiview - 更改 CALayer 的大小也会更改先前添加的图层大小