响应者链浅谈

作者: 阿拉当 | 来源:发表于2016-07-13 15:46 被阅读221次

响应者对象

响应者对象(Response object) 响应者对象就是可以响应事件并对事件作出处理。iOS中UIResponder类,定义了响应者对象的所有方法。UIApplication、UIView等类都继承了UIResponder类,UIWindow和UIKit框架下的控件,因为继承了UIView,所以也属于响应者类

第一响应者

当前接受触摸的响应者对象,它是响应者链的开端。事件首先被发送给第一响应者,第一响应者往往是事件发生的视图,也就是用户触摸屏幕的地方。事件将沿着响应者链一直向下传递,直到被接受并做出处理。

响应者链

响应者链表示一系列的响应者对象。事件交由第一响应者对象处理,如果第一响应者对象不处理,事件被沿着响应者链向上传递,交给下一个响应者(next responder)。

事件传递的过程

  • 先将事件对象由上往下传递(由父控件传递给子控件),找到最合适的控件来处理这个事件。 调用最合适控件的touches….方法,如果调用了[super touches….];就会将事件顺着响应者链往上传递,传递给上一个响应者对象,接着就会调用上一个响应者对象的touches….方法。
  • iOS系统检测到手指触摸(Touch)操作时会将其打包成一个UIEvent对象,并放入当前活动Application的事件队列,单例的UIApplication会从事件队列中取出触摸事件并传递给单例的UIWindow来处理,UIWindow对象首先会使用hitTest:withEvent:方法寻找此次Touch操作初始点所在的视图(View),即需要将触摸事件传递给其处理的视图,这个过程称之为hit-test view。
  • UIWindow实例对象会首先在它的内容视图上调用hitTest:withEvent:,此方法会在其视图层级结构中的每个视图上调用pointInside:withEvent:(该方法用来判断点击事件发生的位置是否处于当前视图范围内,以确定用户是不是点击了当前视图),如果pointInside:withEvent:返回YES,则继续逐级调用,直到找到touch操作发生的位置,这个视图也就是要找的hit-test view。首先调用当前视图的pointInside:withEvent:方法判断触摸点是否在当前视图内;若返回NO,则hitTest:withEvent:返回nil;若返回YES,则向当前视图的所有子视图(subviews)发送hitTest:withEvent:消息,所有子视图的遍历顺序是从最顶层视图一直到到最底层视图,即从subviews数组的末尾向前遍历,直到有子视图返回非空对象或者全部子视图遍历完毕;若第一次有子视图返回非空对象,则hitTest:withEvent:方法返回此对象,处理结束;如所有子视图都返回非,则hitTest:withEvent:方法返回自身(self)。

响应者链的传递过程

响应者链传递图
  • 正常的响应者链流程经常被委托(delegation)打断,一个对象(通常是视图)可能将响应工作委托给另一个对象来完成(通常是视图控制器ViewController),这就是为什么做事件响应时在ViewController中必须实现相应协议来实现事件委托。先将事件对象由下往上传递,由父控件传递给子控件,找到最合适的控件来处理这个事件(调用touches...方法)。如果调用了super的touches方法,就会将事件顺着响应者链条往上传递,传递给上一个响应者的touches方法。
  • 第一响应者——> 第一响应者的视图控制器(如果有)——>父容器(如果有)——>父容器的视图控制器(如果有)——>UIWindow——>UIApplication——>应用程序委托对象
    相应的线路图如下:

First Responser -- > The Window -- >The Application -- > App Delegate

不能响应的几种情况

  • 不接受交互
  • 隐藏
  • 透明度为0-0.01

发生触摸事件后,系统会将该事件加入UIApplication管理的事件队列中。UIApplication会从事件队列中取出最前面的事件,并将事件分发下去以便处理,通常,先发送事件给应用程序主窗口。触摸事件通过父控件传递到子控件。
例如有1->2->3->4->5这么几层View,点击事件需要通过UIApplication传给UIWindow,然后向子控件传递。
如果父控件拒绝接收事件,那么点击子控件是无效的。
如果传递链在中间断开,则会交给断点前的控制器处理。
例如3->4处损坏,点击5会由3处理,如果5拒绝接收,会由4处理。
图片默认的userInteractionEnabled为NO,默认不接收事件,因此不会遮盖下面的视图接收触摸事件。
以后发现按钮不管用,检查父控件是否userInterationEnabled为YES,例如图片上的按钮。
imageView的响应为YES,会把事件回抛到父控件(响应者链条)。
事件顺着响应者链条向上传递,找到最合适的控件调用touches....方法。
可以实现事件的回传。
1->2->3 三层
如果要实现2、3都监听触摸,调用3的super的touches...方法即可。

补充:如果经过上面的传播过程,还没有被处理,那么该事件就会被丢弃。
(从网上看了一些自己总结整理了一些,不是很全有待补充)

相关文章

  • 响应者链浅谈

    响应者对象 响应者对象(Response object) 响应者对象就是可以响应事件并对事件作出处理。iOS中UI...

  • iOS 响应链

    iOS开发 - 事件传递响应链iOS 响应者链,事件的传递事件传递之响应链Cocoa Touch事件处理流程--响...

  • UIKit之触摸、响应者链

    触摸 响应者链 //响应者链多个响应者组成的链//首先执行检测过程,信息先从UIApplication->Appd...

  • ios响应者链

    iOS 响应者链 字数418 阅读41 评论0 喜欢3 响应者链 响应者链是一个响应者的连接序列,事件或者动作消息...

  • 转载:响应者链工作原理

    响应者链 响应者链是由一个一个响应者组成的长链;响应者链定义了iOS中触摸事件的交互规则;如果hit-test检测...

  • iOS UI事件传递与响应者链

    iOS UI事件传递与响应者链 响应者链 响应者对象:继承自UIResponder的对象称之为响应者对象。UIAp...

  • Swift学习笔记Day0726

    响应者链: 当Application Kit在应用程序中构造对象时,会为每个窗口建立响应者链。响应者链中的基本对象...

  • 基于ResponderChain的事件传递

    ResponderChain对象交互方式本质 响应者链简介 Responder Chain也就是响应链,响应者链是...

  • 响应者链

    1.1 响应者链 当与某控件交互时,该控件将作为"第一响应者 (First Responder)",作为响应者链的...

  • iOS响应者链

    iOS响应者链

网友评论

本文标题:响应者链浅谈

本文链接:https://www.haomeiwen.com/subject/vuojjttx.html