手势识别(六)调节触摸到视图的传递

来源:互联网 发布:问道手游sf源码 编辑:程序博客网 时间:2024/06/05 19:16

Regulating the Delivery of Touches to Views

六、调节触摸到视图的传递

There may be times when you want a view to receive a touch before a gesture recognizer. But, before you can alter the delivery path of touches to views, you need to understand the default behavior. In the simple case, when a touch occurs, the touch object is passed from the UIApplication object to the UIWindow object. Then, the window first sends touches to any gesture recognizers attached the view where the touches occurred (or to that view’s superviews), before it passes the touch to the view object itself.

可能有时候你想要在手势识别器之前接收到一个触摸。但是在你可以改变触摸到视图的传递路径之前,你需要理解其默认行为。在简单情况下,当一个触摸发生时,触摸对象从UIApplication对象传递到UIWindow对象。 然后,窗口首先把触摸发送给触摸发生的视图上关联的任何手势识别器,而不是先发送给视图对象自身。

Figure 1-5  Default delivery path for touch events

图1-5 触摸事件的默认传递路径

Gesture Recognizers Get the First Opportunity to Recognize a Touch

1、手势识别器首先识别一个触摸

window delays the delivery of touch objects to the view so that the gesture recognizer can analyze the touch first. During the delay, if the gesture recognizer recognizes a touch gesture, then the window never delivers the touch object to the view, and also cancels any touch objects it previously sent to the view that were part of that recognized sequence.

For example, if you have a gesture recognizer for a discrete gesture that requires a two-fingered touch, this translates to two separate touch objects. As the touches occur, the touch objects are passed from the app object to the window object for the view where the touches occurred, and the following sequence occurs, as depicted in Figure 1-6.

窗口延迟把触摸对象传递给视图,这样手势识别器就可以首先分析触摸。延迟期间,如果手势识别器识别出一个触摸手势,然后窗口就绝不会再把触摸对象传递给视图,并且还取消任何先前传递给视图的任何触摸对象,这些触摸对象都是被识别序列的一部分。比如,如果你有一个手势识别器用来识别一个离散手势,该手势要求一个双手指的触摸,该触摸就会被解释成两个单独的触摸对象。 当触摸发生时,触摸对象从英语程序对象传递到触摸发生视图的窗口对象,然后发生以下序列,请看图1-6。

Figure 1-6  Sequence of messages for touches

图1-6 触摸消息序列

    1. The window sends two touch objects in the Began phase—through the touchesBegan:withEvent: method—to the gesture recognizer. The gesture recognizer doesn’t recognize the gesture yet, so its state is Possible. The window sends these same touches to the view that the gesture recognizer is attached to.

       窗口在Began 阶段发送两个触摸对象---通过 touchesBegan:withEvent: 方法---给手势识别器。 手势识别器还不能识别该手势,因此它的状态是Possible. 窗口发送这些同样的触摸给手势识别器相关联的视图。

     2. The window sends two touch objects in the Moved phase—through the touchesMoved:withEvent: method—to the gesture recognizer. The recognizer still doesn’t detect the gesture, and is still in state Possible. The window then sends these touches to the attached view.

      窗口在Moved阶段发送两个触摸对象---通过touchesMoved:withEvent: 方法---- 给手势识别器。 识别器任然不能侦测该手势,状态还是Possible。 窗口然后发送这些触摸到相关联的视图。

     3. The window sends one touch object in the Ended phase—through the touchesEnded:withEvent: method—to the gesture recognizer. This touch object doesn’t yield enough information for the gesture, but the window withholds the object from the attached view.

      窗口在Ended阶段发送一个触摸对象--- 通过touchesEnded:withEvent: 方法---给手势识别器。 虽然该触摸对象对于手势来说信息还不够,但是窗口还是把该对象扣住(withhold)不发送给视图。

     4. The window sends the other touch object in the Ended phase. The gesture recognizer now recognizes its gesture, so it sets its state to Recognized. Just before the first action message is sent, the view calls the touchesCancelled:withEvent: method to invalidate the touch objects previously sent in the Began and Moved phases. The touches in the Ended phase are canceled.

      窗口在Ended阶段发送另一个触摸。 手势识别器这是可以识别出该手势,因此把状态设置为Recognized. 就在第一个操作信息被发送之前,视图调用touchesCancelled:withEvent: 方法来使先前在Began 和Moved阶段发送的触摸对象无效(invalidate)。触摸在Ended阶段被取消。

 

Now assume that the gesture recognizer in the last step decides that this multitouch sequence it’s been analyzing is not its gesture. It sets its state toUIGestureRecognizerStateFailed. Then the window sends the two touch objects in the Ended phase to the attached view in a touchesEnded:withEvent:message.

现在假设手势识别器在最后一步确定它正在分析的多点触摸序列不是它的手势。它把状态设置为UIGestureRecognizerStateFailed.。 然后窗口在Ended阶段发送这两个触摸对象给相关联的视图---通过touchesEnded:withEvent: 消息。

A gesture recognizer for a continuous gesture follows a similar sequence, except that it is more likely to recognize its gesture before touch objects reach the Ended phase. Upon recognizing its gesture, it sets its state to UIGestureRecognizerStateBegan (not Recognized). The window sends all subsequent touch objects in the multitouch sequence to the gesture recognizer but not to the attached view.

一个连续手势的手势识别器遵循一个相似的序列,除了它更有可能在触摸对象到达Ended 阶段之前就识别出它的手势。一旦识别出它的手势,它把状态设置为 UIGestureRecognizerStateBegan (而不是Recognized). 窗口把多点触摸序列中的所有子序列触摸对象发送给手势识别器,而不是发送到附属的(attached)视图。

Affecting the Delivery of Touches to Views

2、影响到视图的各个触摸的传递

You can change the values of several UIGestureRecognizer properties to alter the default delivery path in certain ways. If you change the default values of these properties, you get the following differences in behavior:

你可以改变 UIGestureRecognizer 特性的几个值来改变默认传递路径,让它们以特定的方式传递。如果你改变这些特性的默认值,以下行为将发生变化:

  • delaysTouchesBegan (default of NO)—Normally, the window sends touch objects in the Began and Moved phases to the view and the gesture recognizer. Setting delaysTouchesBegan to YES prevents the window from delivering touch objects in the Began phase to the view. This ensures that when a gesture recognizer recognizes its gesture, no part of the touch event was delivered to the attached view. Be cautious when setting this property because it can make your interface feel unresponsive.

    This setting provides a similar behavior to the delaysContentTouches property on UIScrollView; in this case, when scrolling begins soon after the touch begins, subviews of the scroll-view object never receive the touch, so there is no flash of visual feedback.

  • delaysTouchesBegan(默认为NO)---正常情况下,窗口在Began 和 Moved 阶段把触摸对象发送给视图和手势识别器。 把delaysTouchesBegan设置为YES,使得窗口不会在Began阶段把触摸对象发送给视图。 这样做确保一个手势识别器识别它的手势时,没有把部分触摸事件传递给相连的视图。 设置该特性时请谨慎,因为它会使你的界面反应迟钝。
  • delaysTouchesEnded (default of YES)—When this property is set toYES, it ensures that a view does not complete an action that the gesture might want to cancel later. When a gesture recognizer is analyzing a touch event, the window does not deliver touch objects in the Ended phase to the attached view. If a gesture recognizer recognizes its gesture, the touch objects are canceled. If the gesture recognizer does not recognize its gesture, the window delivers these objects to the view through a touchesEnded:withEvent: message. Setting this property to NO allows the view to analyze touch objects in the Ended phase at the same time as the gesture recognizer.

    Consider, for example, that a view has a tap gesture recognizer that requires two taps, and the user double taps the view. With the property set to YES, the view gets touchesBegan:withEvent:touchesBegan:withEvent:touchesCancelled:withEvent:, and touchesCancelled:withEvent:. If this property is set to NO, the view gets the following sequence of messages: touchesBegan:withEvent:touchesEnded:withEvent:touchesBegan:withEvent:, andtouchesCancelled:withEvent:, which means that in touchesBegan:withEvent:, the view can recognize a double tap.

  • delaysTouchesEnded(默认为YES)---当该特性被设置为YES时,它确保视图不会完成一个动作,而该动作是手势可能想在稍候取消的。当一个手势识别器正在分析一个触摸事件时,窗口不会不会在Ended阶段传递触摸对象到相连的视图。如果一个手势识别器识别出它的手势,则触摸对象被取消。 如果手势识别器没有识别出它的手势,窗口通过一个touchesEnded:withEvent:消息把这些对象传递给视图。设置该特性为NO,允许视图和手势识别器可以同时在Ended阶段分析触摸对象。

    例如,设想一个视图有一个点击手势识别器,它要求双击,然后用户双击了该视图。 把特性设置为YES后,视图获得touchesBegan:withEvent:touchesBegan:withEvent:touchesCancelled:withEvent:, 以及 touchesCancelled:withEvent: 信息序列。如果该特性被设置为NO,视图获得以下信息序列:touchesBegan:withEvent:touchesEnded:withEvent:touchesBegan:withEvent:, andtouchesCancelled:withEvent: ,它表示在touchesBegan:withEvent: 消息中,视图可以识别一个双击。

If a gesture recognizer detects a touch that it determines is not part of its gesture, it can pass the touch directly to its view. To do this, the gesture recognizer callsignoreTouch:forEvent: on itself, passing in the touch object.

如果一个手势识别器侦测到一个不属于该手势的触摸,它可以把该触摸直接传递给它的视图。 要想实现它,手势识别器对自己调用ignoreTouch:forEvent:方法,它在触摸对象中传递。

0 0
原创粉丝点击