【问题标题】:how does UIGestureRecognizer works with UIResponder chain?UIGestureRecognizer 如何与 UIResponder 链一起工作?
【发布时间】:2017-04-27 03:39:31
【问题描述】:

我知道触摸事件可以传递到点击视图或手势。但在我的演示中有些东西让我感到困惑:

我的根视图中有两个子视图,一个是 testView(UIView 的子类),另一个是 testBtn(UIButton),它的操作是“testBtnClicked”。然后,我将 UITapGestureRecognizer 添加到我的根视图并将其操作设置为“tapAction”。

问题来了:

当我触摸根视图时,它会触发“touchsBegan:withEvent:”、“tapAction”和“touchsCancelled:withEvent”方法。这正是我所期望的;

当我触摸 testView 时,它的工作原理与上面相同;

当我点击testBtn时,它只触发了“testBtnClicked”方法。为什么?

为什么当我触摸 testView 而不是根视图时手势被识别?以及为什么当我触摸 testBtn 时它无法识别?

【问题讨论】:

    标签: uigesturerecognizer uiresponder


    【解决方案1】:

    啊哈!也许我得到了答案:

    首先,gestureRecognizers 获得了识别触摸的第一个机会,正如 App Doc 所说:

    窗口延迟触摸对象到视图的传递,以便手势识别器可以首先分析触摸。在延迟期间,如果手势识别器识别出触摸手势,则窗口永远不会将触摸对象传递给视图,并且还会取消它之前发送给视图的任何触摸对象,这些对象属于该识别序列的一部分。

    其次,在 iOS 6.0 及更高版本中,UIButton 操作可防止重叠手势识别器行为,正如 Apple Doc 所说:

    在 iOS 6.0 及更高版本中,默认控制操作可防止重叠的手势识别器行为。例如,按钮的默认操作是单击。如果您将单击手势识别器附加到按钮的父视图,并且用户点击按钮,则按钮的操作方法会接收触摸事件而不是手势识别器。这仅适用于与控件的默认操作重叠的手势识别,其中包括:

    • 单指单击 UIButton、UISwitch、UIStepper、 UISegmentedControl 和 UIPageControl。
    • 单指轻扫 UISlider 的旋钮,方向与滑块平行。
    • UISwitch 旋钮上的单指平移手势,方向与开关平行。

    如果您有这些控件之一的自定义子类并且想要更改默认操作,请将手势识别器直接附加到控件而不是父视图。然后,手势识别器首先接收到触摸事件。与往常一样,请务必阅读 iOS 人机界面指南,以确保您的应用提供直观的用户体验,尤其是在覆盖标准控件的默认行为时。

    【讨论】:

      【解决方案2】:

      我知道这已经晚了几年,但答案中似乎缺少一条重要信息:UIButton 使用UIView 的实例方法gestureRecognizerShouldBegin(_:) 来停止跟踪触摸事件。

      UIKitUITouchUIEvent 的实例交给UIButton 时,UIGestureRecognizer.State 仍处于.possible 并尚未被完全识别。正如 OP 所提到的,UIGestureRecognizer 首先检查触摸对象,但是通过将gestureRecognizerShouldBegin(_:) 设置为返回falseUIButton 认为.possible 状态已转换为.failed,并避免爬上@ 987654336@ 链,在上面的例子中它是根视图。这就是为什么不触发根视图中的UIGestureRecognizer 的原因。

      UIGestureRecognizer 不受影响,UIButton 的默认操作被触发。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-03-28
        • 2014-03-21
        • 2020-09-29
        • 2023-02-02
        • 2023-03-24
        • 2014-12-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多