我知道触摸事件可以传递到点击视图或手势。但在我的演示中让我困惑的是:
我的根视图中有两个子视图,一个是testView(UIView的子类),另一个是testBtn(UIButton),其动作是" testBtnClicked"。然后,我将UITapGestureRecognizer添加到我的根视图中,并将其操作设置为" tapAction"。
问题来了:
当我触摸根视图时,它会触发" touchsBegan:withEvent:" ," tapAction"和" touchsCancelled:withEvent"方法。这就是我的预期;
当我触摸testView时,它的工作原理与上面相同;
当我触摸testBtn时,它只触发" testBtnClicked" method.Why?
当我触摸testView而不是根视图时,为什么会识别手势?以及当我触摸testBtn时它为什么不被识别?
答案 0 :(得分:7)
啊哈!可能是我得到了答案:
首先,gestureRecognizers获得第一次识别触摸的机会,正如App Doc所说:
窗口延迟将触摸对象传递到视图,以便手势识别器可以首先分析触摸。在延迟期间,如果手势识别器识别出触摸手势,则窗口从不将触摸对象传递给视图,并且还取消先前发送到视图的任何触摸对象,该触摸对象是该识别序列的一部分。
其次,在iOS 6.0及更高版本中,UIButton操作可防止重叠的手势识别器行为,同样如Apple Doc所述:
在iOS 6.0及更高版本中,默认控件操作可防止重叠手势识别器行为。例如,按钮的默认操作是单击。如果您将单击手势识别器附加到按钮的父视图,并且用户点击该按钮,则该按钮的操作方法将接收触摸事件而不是手势识别器。这仅适用于与控件的默认操作重叠的手势识别,其中包括:
如果您有其中一个控件的自定义子类并且想要更改默认操作,请将手势识别器直接附加到控件而不是父视图。然后,手势识别器首先接收触摸事件。与往常一样,请务必阅读iOS人机界面指南,以确保您的应用程序提供直观的用户体验,尤其是在覆盖标准控件的默认行为时。
答案 1 :(得分:0)
我知道这已经晚了几年,但是答案中似乎缺少一条重要的信息:UIButton
使用UIView
的实例方法gestureRecognizerShouldBegin(_:)来停止跟踪触摸事件。
当UITouch
将UIEvent
和UIButton
的实例移交给UIKit
时,UIGestureRecognizer.State
仍位于.possible
处并具有尚未被完全认可。如OP所述,UIGestureRecognizer
首先要检查触摸对象,但是通过将gestureRecognizerShouldBegin(_:)
设置为返回false
,UIButton
认为.possible
状态已转换为.failed
,并避免爬上UIGestureRecognizer
链,这在上面的示例中已经成为根视图。这就是为什么未触发根视图中的UIGestureRecognizer
的原因。
在UIGestureRecognizer
不起作用的情况下,将触发UIButton
的默认操作。