UIGestureRecognizer如何与UIResponder链一起使用?

时间:2016-12-12 09:49:28

标签: uigesturerecognizer uiresponder

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

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

问题来了:

当我触摸根视图时,它会触发" touchsBegan:withEvent:" ," tapAction"和" touchsCancelled:withEvent"方法。这就是我的预期;

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

当我触摸testBtn时,它只触发" testBtnClicked" method.Why?

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

2 个答案:

答案 0 :(得分:7)

啊哈!可能是我得到了答案:

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

  

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

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

  

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

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

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

答案 1 :(得分:0)

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

UITouchUIEventUIButton的实例移交给UIKit时,UIGestureRecognizer.State仍位于.possible处并具有尚未被完全认可。如OP所述,UIGestureRecognizer首先要检查触摸对象,但是通过将gestureRecognizerShouldBegin(_:)设置为返回falseUIButton认为.possible状态已转换为.failed,并避免爬上UIGestureRecognizer链,这在上面的示例中已经成为根视图。这就是为什么未触发根视图中的UIGestureRecognizer的原因。

UIGestureRecognizer不起作用的情况下,将触发UIButton的默认操作。