美文网首页
响应链详解

响应链详解

作者: ibingewin | 来源:发表于2018-03-10 16:27 被阅读12次

    响应链

    顾名思义,响应链就是对某些行为的响应,按照一定的机制进行流动,所形成的链条

    iOS中:用户点击屏幕时,会触发以下流程:

    1. 捕获事件:手机系统捕获到单击行为,也称为单击事件
    2. 封装事件:把包含该事件的信息封装成UITouchUIEvent对象
    3. 查找程序:找到可以处理该事件的运行程序
    4. 查找第一响应者:利用hitTest:(CGPoint)point方法,在视图层级中,从下往上逐级查找可以响应该事件的响应者,将最后的响应者作为第一响应者
    5. 事件转发:如果第一响应者不处理该事件,再用nextResponder方法,从上往下,逐级转发,直到没有响应者响应。

    如下图所示:用户点击输入框时,UITextField就成为第一响应者,如果它不处理该点击事件,就转发该事件给它的superView,如果有视图控制器,就转给视图控制器,接着再到UIWindow,再到UIApplication,最终到AppDelegate,如果AppDelegate也不处理,该事件就被丢弃

    image

    这个过程就是事件的响应链

    这里提到几个概念:事件响应者第一响应者,下面分别进行介绍:

    事件

    用户跟iOS设备的交互行为就称为事件

    iOS中,有4种事件类型:

    1. 点击事件:在屏幕上的点击
    2. 移动事件:指的是设备的移动,如摇晃,与Core Motion的移动不同
    3. 远程控制事件:指的是从耳际或其它附件上接收到的指令,大多用来控制多媒体,如调整音量,切换歌曲等
    4. 按压事件:指设备上的物理按钮按压操作

    响应者

    响应者是用于响应和处理事件的抽象接口

    iOS中,响应者都是UIResponder类的实例,它是事件处理的核心对象,包括常用的UIViewUIWindowUIApplicationUIViewController

    第一响应者

    App接收到事件时,UIKit框架会自动将该事件派给最合适的响应者,这个响应者就是第一响应者

    决定谁是第一响应者

    iOS中,第一响应者取决于事件类型

    1. 点击事件:第一响应者是事件发生所在的view
    2. 按压事件:第一响应者是获取焦点的响应者
    3. 移动事件:第一响应者由开发者指定
    4. 远程控制事件:第一响应者由开发者指定
    5. 编辑菜单消息:第一响应者由开发者指定
    注意:关于加速计、陀螺仪、磁力计等的移动事件,不遵循响应链规则,由Core Motion框架处理
    

    然而,当事件发生时,第一响应者并不总是来立即处理该事件,当对象是Control,或者该对象有Gesture recognizer时,会进行额外的处理。

    1. ControlControls与关联的target目标对象,是通过action消息机制进行通信的。当用户与control交互时,control会先调用targetaction方法。如果controltarget为空,UIKit就会按照响应链来处理该事件。
    2. Gesture recognizer:如果一个view添加有手势识别器,会先用手势识别器来处理事件,如果所有的手势识别器都不能处理事件,才会传给view处理,之后遵循响应链。

    决定哪个响应者来接收触摸事件

    UIKit是通过视图层的hit-testing方法来决定,触摸事件发生的位置。

    UIKit会调用方法hitTest方法,由下往上,逐一遍历视图层,通过pointInside方法将触摸点所在的位置坐标与视图进行比较,最终查到的最顶层的view就是接收该事件的第一响应者

    注意:如果触摸点在视图区域的外边,该视图及所在的子视图分支整个都将被忽略。比如:一个view的 clipsToBounds属性为NOsubview就可以有部分显示在该view的外面,对外面这部分的触摸事件,在执行``pointInside方法与view比较时会返回NO,结果导致该view`及子视图分支被忽略

    一旦触摸事件发生,UIKit就会给包含该触摸点的view分配一个touch对象,该对象在整个触摸周期中,位置和内部参数可能会发生变化,但它的view属性,永远不变,哪怕触摸点已经离开了view的视图范围

    改变响应链

    可以通过重写nextResponder方法,来选择下一个响应者

    许多UIKit类都通过重写该方法,来返回指定的对象

    • UIView:如果是viewController的根视图,next responder就是viewController,否则就是superView
    • UIViewController:如果是window的根视图控制器,next responder就是window;如果是由另一个视图控制器模态出来的,next responder就是该视图控制器
    • UIWindownext responderUIApplication对象
    • UIApplication:如果AppDelegateUIResponder的对象,且不是viewview controllerapplication,那么next responder就是AppDelegate

    相关文章

      网友评论

          本文标题:响应链详解

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