iOS事件处理中响应链

2019-11-21  本文已影响0人  FY_Chao

在App的使用过程中,事件会在App中流转来寻找适合的响应者来针对事件响应。在本篇文章中。我们来了解下事件、响应者及响应链。

响应者

首先我们来看下什么是响应者,响应者顾名思义是针对事件作出处理的对象。在 iOS 中响应者对象就是 UIResponder的实例。在 UIKit 框架中我们可以看到很多重要的对象都继承自UIResponder,包括:

UIResponder 继承图示

事件

App收到一个事件后, 系统会自动派发事件到合适的响应者来处理。在iOSUIEvent代表一个UIKit事件,目前UIEvent包含以下类型事件:

1. 触摸事件 touch events,最常见也是最常处理事件。
2. 运动事件 motion events,由`UIKit`触发的,与Core Motion框架息息相关。
3. 远程控制事件 remote-control events,远程控制事件允许响应者对象从外部附件或耳机接收命令,以便它可以管理音频和视频。
4. 按压事件 press events,常出现在 `game controller`, `AppleTV 遥控器, 或者其他具有物理按钮的设备交互时。

ps:以下内容皆以触摸事件 touch events为例。

在iOS中一个touch事件可能包含一个或者多个UITouch对象,如用户双指触碰屏幕,此时产生的一个触碰事件中有两个UITouch对象,每个UITouch对象对应一个手指。

而在一个触摸事件产生之后,系统会将事件传递给合适的UIResponder对象并调用相应的处理方法。在UIResponder中默认实现了响应的事件理方法,如处理touch events

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event; // 外部打断,如电话的呼入。
touches方法调用的时间点

如何寻找到合适的View处理事件

UIKit会用Touch事件的位置与视图层次结构中视图对象的bounds进行比较。遍历视图层次结构的hitTest:withEvent:方法,查找包含触摸事件的最深子视图,该子视图成为触摸事件的第一响应者。

大概步骤:

  1. 判断Touch事件的location是否在自己bounds内。如果是进行下一步,如果不是则忽略
  2. 遍历自身的子视图,Touch事件的location是否在子视图bounds
  3. 重复第一、第二步,直到没有子视图。则自己就是

UIView不能接收触摸事件的四种情况:

响应链

响应者接收事件数据后,必须处理事件或将其转发到另一个响应者对象。未处理的事件从响应者传递到下一个响应者,这个传递过程称之为响应链。

UIKit的传递过程中,下一个响应者由nextResponder决定,许多UIKit类已经重写此属性并返回特定的对象,如下:

响应链图示
上一篇 下一篇

猜你喜欢

热点阅读