【问题标题】:UIView catch touch events and pass throughtUIView 捕捉触摸事件并通过
【发布时间】:2018-04-02 17:37:51
【问题描述】:

我想实现UIView 子类,它将捕获所有触摸事件(尤其是 touchesMoved)并传递它们。有可能吗?

class PassthroughView: UIView {

    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
        let view = super.hitTest(point, with: event)
        return view == self ? nil : view
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        print("touchesBegan")
        super.touchesBegan(touches, with: event)
    }

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        print("touchesMoved") //not called
        super.touchesMoved(touches, with: event)
    }

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        print("touchesEnded")
        super.touchesEnded(touches, with: event)
    }
}

【问题讨论】:

    标签: swift uiview touches


    【解决方案1】:

    你真的不能这样做。如果您的视图接收到触摸,则它无法将其传递给如果您的视图不存在时将收到的视图。为此,您基本上必须重新实现整个事件路由。如果不访问 Apple 内部 API,这将非常困难,甚至是不可能的。但即使你做对了,它也可能会随着每次 iOS 更新而中断。

    但是有一种不同的方法可以获取所有触摸事件,同时仍将它们传递到适当的视图。为此,您创建UIApplication 的子类并覆盖sendEvent(_:) 方法。这为每个事件调用并将其分派到适当的视图。从那里您可以先进行特殊处理,然后像往常一样致电super.sendEvent() 将其发送到您的窗口。

    当然,您不会收到不同的触摸开始/移动/结束调用,但信息在您的事件对象中。首先你需要检查event.type 属性,看看你是否真的得到了一个触摸事件。如果是这样,您可以从event.allTouches 属性中获取所有信息。对于每次触摸,您都可以获得phase,它描述了此触摸是否开始、移动、结束等等。

    当然子类化是不够的,你还必须告诉系统使用你的新子类。为此,您将其注释为@objc(MyApplication),其中MyApplication 是类的名称。这确保了 Objective-C 运行时可以通过你给它的名字找到这个类。然后编辑 Info.plist 文件并为“主体类”键设置此名称。 (如果您不使用 Xcode 编辑器,该键也称为 NSPrincipalClass)。

    【讨论】:

      猜你喜欢
      • 2011-06-03
      • 1970-01-01
      • 2014-07-27
      • 2011-08-12
      • 2018-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-07
      相关资源
      最近更新 更多