[译] iOS | 官方文档 | 使用响应者和响应者链处理事件

前言

译自官方文档:Using Responders and the Responder Chain to Handle Eventsapp

概览

App 使用响应者对象接收和处理事件。一个响应者对象能够是UIResponder类的任何实例,常见的子类包括UIViewUIViewControllerUIApplication。响应者接收原始事件数据,而且必定会处理事件或将其发送给另外一个响应者对象。当 app 接收到事件时,UIKit会自动将该事件定向到最合适的响应者对象,即第一响应者(the first responder)。框架

未处理的事件会在一个活动的响应者链中,从一个响应者传递到另外一个响应者,这是响应者对象的动态配置(?)。 下图显示了一个 app 中的响应者,该程序的界面包含一个UILabel,一个UITextField,一个UIButton和两个背景UIView。 该图还显示了事件如何沿着响应者链从一个响应者转移到下一个响应者。测试

若是UITextField不处理事件,则UIKit会将事件发送到UITextField的父视图,而后再接下来会发送到UIWindow的根视图。从根视图开始,响应程序链在将事件定向到UIWindow以前转移到当前持有的UIViewController。若是UIWindow没法处理事件,则UIKit会将事件传递给UIApplication对象,若是该对象是UIResponder的实例而且还不是响应者链的一部分,则可能传递给app delegate(?)。ui

肯定一个事件的第一响应者

UIKit是根据事件的类型将对象指定为该事件的第一响应者。事件类型包括:code

事件类型 第一响应者
Touch events 发生触摸的视图
Press events 被 focus 的对象
Shake-motion events 你(或UIKit)指定的对象
Remote-control events 你(或UIKit)指定的对象
Editing menu messages 你(或UIKit)指定的对象

注意cdn

与加速度计,陀螺仪和磁力计有关的运动事件不遵循响应程序链。 相反,Core Motion 会将这些事件直接传递到指定的对象。 有关更多信息,请参见 Core Motion 框架。对象

控件使用action信息直接与其关联的目标对象进行通讯。当用户与控件交互时,控件会将action信息发送到其target对象。action消息不是事件,可是它们仍然能够利用响应者链。当控件的目标对象为nil时,UIKit从目标对象开始并遍历响应程序链,直到找到实现适当操做方法的对象为止。例如,UIKit编辑菜单使用此行为来搜索响应者对象,这些对象实现了诸如cut(_ :)copy(_ :)paste(_ :)之类的方法。blog

手势识别器(Gesture recognizers)会比相关视图先接收触摸和按下事件。若是视图的手势识别器没法识别一系列触摸,则UIKit会将触摸发送到视图。 若是视图没法处理触摸,UIKit会将它们向上传递到响应者链。 有关使用手势识别器处理事件的更多信息,请参见处理UIKit手势。事件

肯定是哪一个响应者包含了触摸事件

UIKit使用基于视图的命中测试(hit-testing)来肯定触摸事件发生的位置。具体来讲,UIKit将触摸位置与视图层次结构中视图对象的边界(bounds of view objects)进行比较。UIViewhitTest(_:with :)方法会遍历视图层次结构,查找包含指定触摸的最深子视图,该子视图成为触摸事件的第一响应者。ip

注意

若是触摸位置在视图范围(a view’s bounds)以外,则hitTest(_:with :)方法将忽略该视图及其全部子视图。所以,若是视图的clipsToBounds属性为false,即便该视图刚好包含触摸,也不会返回该视图范围以外的子视图。有关命中测试(hit-testing)行为的更多信息,请参见UIView中有关hitTest(_:with :)方法的讨论。

发生触摸时,UIKit将建立一个UITouch对象并将其与视图关联。 随着触摸位置或其余参数的更改,UIKit会使用新信息更新那个UITouch对象。 惟一不变的属性是那个关联的视图。 (即便触摸位置移到原始视图以外,触摸的视图属性中的值也不会更改。)触摸结束时,UIKit会释放UITouch对象。

改变响应者链

您能够经过覆盖响应者对象的next(指响应链中下一个响应者)属性来更改响应者链。

许多UIKit类已经重写此属性并返回特定的对象,包括:

  • UIView,若是视图是UIViewController的根视图,则下一个响应者是UIViewController。不然,下一个响应者是视图的父视图。

  • UIViewController

    • 若是UIViewController的视图是UIWindow的根视图,则下一个响应者是UIWindow对象。

    • 若是UIViewController是由另外一个UIViewController呈现的,则下一个响应者是第二个视图控制器。

  • UIWindow,窗口的下一个响应者是UIApplication对象。

  • UIApplication,下一个响应者是app delegate.但仅当该app delegateUIResponder的实例且不是视图、UIViewController或app对象自己时,才是下一个响应者。

后记

这篇文档讲得很浅,同时也讲的不怎么容易懂,想要更深刻理解响应链及手势相关内容仍是须要阅读更多其余优秀资料。

相关文章
相关标签/搜索