事件类型(Event Type)

iOS 有三种事件类型:

  • 触控事件(UIEventTypeTouches):单点、多点触控以及各种手势操作;
  • 传感器事件(UIEventTypeMotion):重力、加速度传感器等;
  • 远程控制事件(UIEventTypeRemoteControl):远程遥控iOS设备多媒体播放等;

 

响应者对象(Responder Object)

responder object 是能够响应并处理事件的对象,是构成响应链和事件传递链的节点。

举个栗子,当手指去触摸屏幕上 UIView 的实例对象 aView。触摸的动作会产生一个触摸事件 UIEventTypeTouches,而接收触摸事件的对象 aView,就是一个 responder object。

一个事件有可能被多个 responder 接收,第一个接收事件的 responder 就叫 first responder。

在 iOS 中,几乎所有类都是 responder,比如 UIWindow、UIView、UIControl、UIControllers 等,而这些类都有一个共同的父类 —— UIResponder。UIResponder 声明了用于处理事件的接口,并定义了默认的行为。

Responder 继承链如下:


 

响应者链(responder chain)

当一个事件发生时,如果 first responder 不处理,事件就会继续往下传递,被下个 responder 接收,如果下个 responder 也不处理,又会被下下个 responder 接收…… 直到一个 responder 处理了事件或者没有 responder 了。这些 responder 按照传递次序连接起来的链条就构成了响应者链。

iOS 上的响应者链:

由于不同的 app 内的布局和层次结构的不同,响应顺序也会有所不同,但事件的传递路径会遵守基本规则。从图中可以看到,响应者链有以下特点:

  • 响应者链通常是由 initial view 开始;

  • UIView 的 nextResponder 它的 superview;如果 UIView 已经是其所在的 UIViewController 的 top view,那么 UIView 的 nextResponder 就是 UIViewController;

  • UIViewController 如果有 Super ViewController,那么它的 nextResponder 为其 Super ViewController 最表层的 View;如果没有,那么它的 nextResponder 就是 UIWindow;

  • UIWindow 的 contentView 指向 UIApplication,将其作为 nextResponder;

  • UIApplication 是一个响应者链的终点,它的 nextResponder 指向nil,整个 responder chain 结束。

需要说明是,如果当前的 responder 不处理事件,并希望将其传递给 nextResponder 时,需要手动编写代码,才会继续往下传递,否则事件会被废弃。

 
  1. -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
  2. {
  3. // 将事件传递给 nextResponder
  4. id theNextResponder = [self nextResponder];
  5. [theNextResponder touchesBegan:touches withEvent:event];
  6. }

 

Hit-Test View 与 Hit-Testing

当用户与 iPhone 的触摸屏产生互动时,硬件就会探测到物理接触并且通知操作系统。操作系统就会创建相应的事件,并将其传递给当前正在运行的应用程序的事件队列。然后这个事件会被事件循环传递给优先响应对象,即 Hit-Test View 。

Hit-Test View 就是事件被触发时和用户交互的对象,寻找 Hit-Test View 的过程就叫做 Hit-Testing。

首先假设现在有如下这么一个 UI 布局,一种有 A B C D E 五个视图。

假设用户触摸了上图的 View E 区域,那么 iOS 将会按下面的顺序反复检测 subview 来寻找 Hit-Test View

  1. 触摸区域在视图 A 内,所以检测视图 A 的 subview B 和 C;
  2. 触摸区域不在视图 B 内,但是在视图 C 内,所以检查视图 C 的 subview D 和 E;
  3. 触摸区域不在视图 D 内,在视图 E 中;

视图 E 在整个视图体系中是 lowest view,所以视图 E 就是 Hit-Test View 。


 

总结

所以关于事件的链有两条:事件的响应链;Hit-Testing 时事件的传递链。

  • 响应链:由离用户最近的view向系统传递。 
    initial view –> super view –> …..–> view controller –> window –> Application –> AppDelegate

  • Hit-Testing 链:由系统向离用户最近的view传递。 
    UIKit –> active app's event queue –> window –> root view –>……–>lowest view


参考文档 
[1] iOS Developer Library: Event Handling Guide for iOS 
[2] iOS Developer Library: UIKit Framework Reference 
[3] Cocoa Application Competencies for iOS: Responder Object 
[4] Drobnik KG: The Amazing Responder Chain 
[5] 啸笑天: iOS 手势及触摸 
[6] 易荣义: 事件传递之响应链(Event Delivery: The Responder Chain)[译] 
[7] 《随堂笔记iOS UI课程》—— 事件,响应者链,容器视图控制器 
[8] 墨半成霜: Responder一点也不神秘 —— iOS用户响应者链完全剖析 
[9] 唐韧_Ryan: iOS事件机制(一) 
[10] 唐韧_Ryan: iOS事件机制(二)

Events and Responder Chain的更多相关文章

  1. 【IOS笔记】Event Delivery: The Responder Chain

    Event Delivery: The Responder Chain  事件分发--响应链 When you design your app, it’s likely that you want t ...

  2. hitTest:WithEvent 和Responder Chain

    这个方法是找到那个View被touch,当找到后就成为响应链的第一个了,如果他不能处理这个Event,那么就找nextResponder 直至application 如果不能处理,那就会丢弃掉. ht ...

  3. Event Delivery: The Responder Chain(事件传递,响应链)

    当我们设计app的时候,我们很可能想动态的响应事件.例如,触摸一个拥有许多不同对象的屏幕,你要决定给哪个对象一个响应事件,怎么样对象接收到事件. 当一个用户产生事件发生时(如 点击),UIKit产生一 ...

  4. View Controller Programming Guide for iOS---(八)---Using View Controllers in the Responder Chain

    Using View Controllers in the Responder Chain 响应链中使用视图控制器 View controllers are descendants of the UI ...

  5. Event Handling Guide for iOS--(三)---Event Delivery: The Responder Chain

    Event Delivery: The Responder Chain 事件传递:响应链 When you design your app, it’s likely that you want to ...

  6. iOS - Responder Chain

     在iOS中,当发生事件响应时,必须知道由谁来响应事件.这就是由响应者链来对事件进行响应,所有事件响应的类都是UIResponder的子类,响应者链是一个由不同对象组成的层次结构,其中的每个对象将依次 ...

  7. iOS Responder Chain 响应者链

    一.事件分类 对于IOS设备用户来说,他们操作设备的方式主要有三种:触摸屏幕.晃动设备.通过遥控设施控制设备.对应的事件类型有以下三种: 1.触屏事件(Touch Event) 2.运动事件(Moti ...

  8. iOS-响应链(Responder Chain)

    2017.05.08 20:40* 字数 1306 阅读 740评论 6喜欢 9 工作接近一年,很久没有更新博客.工作中学到很多知识点后面将花时间整理,作为对一年知识学习的总结: 下面是本篇博客的写作 ...

  9. iOS事件响应链(Responder Chain)

    概述 在iOS中,视图的层级一般都是 父视图->添加各种子视图.这时候某个视图(子视图)上有个按钮,需要我们交互.但是有时候我们会发现无论如何都没有反应.这时候可能就是我们对iOS的事件传递响应 ...

随机推荐

  1. [其他]Android SDK离线文件路径以及安装更新方法

    一.离线安装Android SDK文件路径 转载自:http://www.oschina.net/code/snippet_1539302_45940 Google TV Addon, Android ...

  2. hibernate内部测试题总结

    在Hibernate中,关于脏检查和刷新缓存说法正确的是(ab ). A.当事务提交时,会发生脏检查 B.Session的flush( )方法是刷新缓存的方法 C.在执行Session的commit( ...

  3. CodeForces 706E Working routine

    十字链表. 开一个十字链表,矩阵中每一格作为一个节点,记录五个量: $s[i].L$:$i$节点左边的节点编号 $s[i].R$:$i$节点右边的节点编号 $s[i].U$:$i$节点上面的节点编号 ...

  4. cocoaPods安装成功终端代码(期间报error: RPC failed; result=56, HTTP code = 200)

    Last login: Sat Oct 15 23:30:24 on ttys002 Sivek_lindeMacBook-Pro:~ Sivek_lin$ sudo gem update --sys ...

  5. JS---控制键盘事件

    键盘事件汇总: 1.onkeydown 键盘按下时触发; 2.onkeyup  键盘按下后抬起触发的事件  3.onkeypress 这个事件在用户按下并放开任何字母数字键时发生(不常用) keyCo ...

  6. 8、关于viewWithTag

    1.viewWithTag检索tag的方法问题viewWithTag方法会对当前View和其子View进行搜索,查找符合tag的对象,但如果view和其多个子view中都含有相同tag值对象时,该方法 ...

  7. java中|与||有什么区别?那么&与&&呢

    ||当左边为真时,就不运行右边的表达式了|当左边为真,还是会运算右边的表达式&&当左边为假时,就不会运算右边的表达式&当左边为假时,还是会运算右边的表达式

  8. Linux Kernel Vhost 架构

    Vhost 回顾 Linux中的vhost驱动程序提供了内核virtio设备仿真. 通常,QEMU用户空间进程模拟guest的I / O访问. Vhost将virtio仿真代码放到内核中,使QEMU用 ...

  9. 解决 git extensions 每次提交需要输入用户名和密码

    打开git bash 输入用户名和密码 git config --global user.name "username" git config --global user.emai ...

  10. Hiver 操作 MySQL 导致锁表

    Hadoop 搬迁到新集群后,操作主库 MySQL 导致了锁表...sad 具体锁表时间点  : 2016-1-14 14:31  到   2016-1-14 14:36 之间 在 oradba 的 ...