ios developer documentation -- 理解事件处理、响应者和响应者链

了解事件如何通过您的应用传播以及如何处理它们。

概述

APP使用响应者对象接收和处理事件。 响应者对象是UIResponder类的任何实例,通用子类包括UIView,UIViewController和UIApplication。响应者接收原始事件数据,并且必须处理该事件或将其转发给另一个响应者对象。 当您的APP收到事件时,UIKit会自动将该事件指向最合适的响应者对象,即第一响应者。未处理的事件从响应者传递到活动响应者链中的响应者,响应者链是应用程序的响应者对象的动态配置。 您的应用中没有单个响应者链。 UIKit为对象如何从一个响应者传递到下一个响应者定义了默认规则,但是您可以随时通过覆盖响应者对象中相应的属性来更改这些规则。图1显示了应用程序中的默认响应者链,其界面包含标签,文本字段,按钮和两个背景视图。 如果文本字段没有处理事件,则UIKit将该事件发送到文本字段的父级UIView对象,然后将该事件发送到窗口的根视图。从根视图中,响应者链在将事件引导到窗口之前转移到拥有的viewcontroller。 如果窗口不处理事件,则UIKit会将事件传递给UIApplication对象,如果该对象是UIResponder的实例而不是响应器链的一部分,则可能将事件传递给APP委托代理。

图1 响应者链在APP中的示意图


确定事件的第一响应者

对于每种类型的事件,UIKit都会指定一个第一响应者,并首先将该事件发送给该对象。 第一响应者根据事件的类型而不同。

  • 触摸事件--第一响应者是发生触摸的视图。
  • 新闻事件--第一响应者是具有焦点的响应者。
  • 摇动事件--第一响应者是您(或UIKit)指定为第一响应者的对象。
  • 远程控制事件--第一响应者是您(或UIKit)指定为第一响应者的对象。
  • 编辑菜单消息--第一响应者是您(或UIKit)指定为第一响应者的对象。

笔记:与加速度计,陀螺仪和磁力计有关的运动事件不遵循响应者链。 相反,Core Motion将这些事件直接发送给您指定的对象。 有关更多信息,请参阅Core Motion Framework。

控件使用动作消息直接与其关联的目标对象通信。 当用户与控件进行交互时,控件会调用其目标对象的动作方法 - 换句话说,它会向其目标对象发送动作消息。动作消息不是事件,但他们仍然可以利用响应者链。 当控件的目标对象为零时,UIKit从目标对象开始并遍历响应者链,直到找到实现相应操作方法的对象。例如,UIKit编辑菜单使用这种行为来搜索响应者对象,这些对象实现名称为cut(_ :),copy(_ :)或paste(_ :)的方法。

如果view具有附加的手势识别器,则手势识别器在视图接收到之前接收触摸和按下事件。 如果所有视图的手势识别器都无法识别其手势,则将事件传递给view进行处理。如果视图不处理它们,UIKit将事件传递给响应者链。 有关使用手势识别器来处理事件的更多信息,请参阅处理UIKit手势。

确定哪个响应者包含触摸事件

UIKit使用基于视图的hit-testing来确定触摸事件发生的位置。 具体来说,UIKit将触摸位置与视图层次结构中视图对象的边界进行比较。 UIView的hitTest(_:with :)方法遍历视图层次结构,查找包含指定触摸的最深的子视图。 该观点成为触摸事件的第一响应者。

笔记:如果触摸位置超出视图边界,hitTest(_:with :)方法会忽略该视图及其所有子视图。 因此,如果某个视图的clipsToBounds属性为false,那么即使它们碰巧包含该触摸,该视图边界外的子视图也不会返回。 有关命中测试行为的更多信息,请参阅UIView中hitTest(_:with :)方法的讨论。

UIKit将每个触摸分配给包含它的视图。 UIKit在触摸第一次出现时创建每个UITouch对象,并且仅在触摸结束后才释放该触摸对象。 随着触摸位置或其他参数的更改,UIKit会使用新信息更新UITouch对象。唯一不变的属性是包含中的视图。 即使触摸位置移动到原始视图之外,触摸视图属性中的值也不会改变。

改变响应者链

您可以通过覆盖响应者对象的下一个属性来改变响应者链。 当你这样做时,下一个响应者就是你返回的对象。

许多UIKit类已经覆盖这个属性并返回特定的对象。

  • UIView对象。 如果视图是视图控制器的根视图,则下一个响应者是视图控制器; 否则,下一个响应者是视图的超视图。
  • UIViewController对象。如果视图控制器的视图是窗口的根视图,则下一个响应者是窗口对象。如果视图控制器由另一视图控制器呈现,则下一个响应者是呈现视图控制器。
  • UIWindow对象。 窗口的下一个响应者是UIApplication对象。
  • UIApplication对象。 下一个响应者是应用程序委托,但前提是应用程序委托是UIResponder的实例,并且不是视图,视图控制器或应用程序对象本身。

猜你喜欢

转载自blog.csdn.net/yx1166/article/details/80080194