IOS中触摸事件(touch event)的分发以及响应者链(The Responder Chain)机制理解
2014-07-26 22:00
881 查看
最近在看官方的Programming Guide, 恰好看到了事件处理这一部分, 结合网上众多贡献者的理解, 我也来分享自己对于这部分的理解.
IOS的应用是基于事件驱动(Event-driven)的, 当我们编写IOS APP的时候, 我们需要做的就是编写代码来处理好IOS运行周期中发生的各个类型的事件. 在IOS APP的生命周期中, 会产生各种各样的事件, 比如电量不足, 突然的来电, 网络连接断开了, 用户手指触碰屏幕等, 都会产生事件.
有些事件是交由系统底层进行处理, 并不会暴露给我们, 而有些事件, 比如触击事件(touch event), 当触击事件在app运行期间发生时, 若处于合适的状态(比如我们的应用处于前台并且是在激活的状态下,激活状态下的应用表现为正在运行并且可以接收事件)这样的事件是可以交由我们的app进行处理的.
这里就来谈谈触击事件(touch event)
假定你的app处于激活状态, 当你点击了屏幕, 系统底层便会收到触击的消息, 然后生成事件(event), 放入事件队列(event queue)中, 对于触击事件, 当事件队列处理到此事件时, 将其交由你的app, 接着, 你的app将这个触击事件与其他相关的信息(与UIKit有关的一些属性)一起打包为一个UIEvent对象.然后UIApplication(你的应用程序单例)对象
将打包的UIEvent(也就是那个触击事件)交由你应用程序的主Window进行分发. 这个过程可以由如下如表示:
上图中, UIWindow在寻找具体的View的过程中, 主要是使用了两个方法,hitTest:withEvent: 与 pointInside:withEvent:这两个方法来寻找发生触击事件的UIView对象.
见下图:
通过这样类似二分搜索的调用这两个方法去寻找触击发生的视图, 下面给出一个例子, 见图:
图中紫色的view就是触击发生的View.
这里需要注意的是,
1.当一个View的子视图的bounds大于View的bounds的时候, 点击子视图在其父视图bounds之外的部分, 是不会响应其触击事件的, 因为当点击在父视图bounds之外的部分时, 父视图的pointInside:withEvent:返回的是NO. 这时候就不会对子视图进行hitTest:withEvent:的调用了.
2.若一个View的(隐藏)hidden属性设置为YES, 或者是禁止用户进行交互(userInteractionEnabled)设置为YES, 以及视图的alpha(透明度)小于0.01.那么这个视图将被hitTest:withEvent:方法忽略.
3.通过重载View的hitTest:withEvent:方法可以实现某些特定的目的.
下面用介绍响应者链(responder chain)
UIKit里面存在一个类, 叫做UIResponder, 这个类能够响应以及处理事件. 而继承这个类的对象都可以作为响应者. UIView, UIApplication, UIViewController, UIWindow都是从这个类里继承的. 响应者构成响应者链, 具体可以看如下图:
对于触击事件, 若发生触击的UIView对象不能处理, 那么事件就进入响应者链中去寻找响应者. 一般来说, 发生触击的hitTest-view作为第一响应者(first responder)处在响应者链的最前面, 响应者对象都有一个nextResponder的方法来获取响应者链中的下一个响应者的引用
参考的文档:
https://developer.apple.com/library/ios/documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/event_delivery_responder_chain/event_delivery_responder_chain.html#//apple_ref/doc/uid/TP40009541-CH4-SW2
IOS的应用是基于事件驱动(Event-driven)的, 当我们编写IOS APP的时候, 我们需要做的就是编写代码来处理好IOS运行周期中发生的各个类型的事件. 在IOS APP的生命周期中, 会产生各种各样的事件, 比如电量不足, 突然的来电, 网络连接断开了, 用户手指触碰屏幕等, 都会产生事件.
有些事件是交由系统底层进行处理, 并不会暴露给我们, 而有些事件, 比如触击事件(touch event), 当触击事件在app运行期间发生时, 若处于合适的状态(比如我们的应用处于前台并且是在激活的状态下,激活状态下的应用表现为正在运行并且可以接收事件)这样的事件是可以交由我们的app进行处理的.
这里就来谈谈触击事件(touch event)
假定你的app处于激活状态, 当你点击了屏幕, 系统底层便会收到触击的消息, 然后生成事件(event), 放入事件队列(event queue)中, 对于触击事件, 当事件队列处理到此事件时, 将其交由你的app, 接着, 你的app将这个触击事件与其他相关的信息(与UIKit有关的一些属性)一起打包为一个UIEvent对象.然后UIApplication(你的应用程序单例)对象
将打包的UIEvent(也就是那个触击事件)交由你应用程序的主Window进行分发. 这个过程可以由如下如表示:
上图中, UIWindow在寻找具体的View的过程中, 主要是使用了两个方法,hitTest:withEvent: 与 pointInside:withEvent:这两个方法来寻找发生触击事件的UIView对象.
见下图:
通过这样类似二分搜索的调用这两个方法去寻找触击发生的视图, 下面给出一个例子, 见图:
图中紫色的view就是触击发生的View.
这里需要注意的是,
1.当一个View的子视图的bounds大于View的bounds的时候, 点击子视图在其父视图bounds之外的部分, 是不会响应其触击事件的, 因为当点击在父视图bounds之外的部分时, 父视图的pointInside:withEvent:返回的是NO. 这时候就不会对子视图进行hitTest:withEvent:的调用了.
2.若一个View的(隐藏)hidden属性设置为YES, 或者是禁止用户进行交互(userInteractionEnabled)设置为YES, 以及视图的alpha(透明度)小于0.01.那么这个视图将被hitTest:withEvent:方法忽略.
3.通过重载View的hitTest:withEvent:方法可以实现某些特定的目的.
下面用介绍响应者链(responder chain)
UIKit里面存在一个类, 叫做UIResponder, 这个类能够响应以及处理事件. 而继承这个类的对象都可以作为响应者. UIView, UIApplication, UIViewController, UIWindow都是从这个类里继承的. 响应者构成响应者链, 具体可以看如下图:
对于触击事件, 若发生触击的UIView对象不能处理, 那么事件就进入响应者链中去寻找响应者. 一般来说, 发生触击的hitTest-view作为第一响应者(first responder)处在响应者链的最前面, 响应者对象都有一个nextResponder的方法来获取响应者链中的下一个响应者的引用
参考的文档:
https://developer.apple.com/library/ios/documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/event_delivery_responder_chain/event_delivery_responder_chain.html#//apple_ref/doc/uid/TP40009541-CH4-SW2
相关文章推荐
- Android触摸事件分发机制之requestDisallowInterceptTouchEvent
- android触摸事件传递机制以及onInterceptTouchEvent()和onTouchEvent()总结
- Android事件分发机制完全解析,带你从源码的角度彻底理解dispatchTouchEvent,onInterceptTouchEvent
- 完全理解Android TouchEvent事件分发机制(一)
- 理解Android中的TouchEvent事件分发机制
- 完全理解Android TouchEvent事件分发机制(二)
- Android事件传递机制以及ViewGroup的onInterceptTouchEvent的理解
- Android 编程下 Touch 事件的分发和消费机制理解
- android事件传递机制以及onInterceptTouchEvent()和onTouchEvent()详解二之小秘与领导的故事
- android事件传递机制以及onInterceptTouchEvent()和onTouchEvent()详解二之小秘与领导的故事
- Android 编程下 Touch 事件的分发和消费机制Android 中与 Touch 事件相关的方法包括:dispatchTouchEvent(MotionEvent ev)、onIntercep
- 【iOS开发-85】利用touch触摸事件:实现画板画画、撤销、清屏以及图片保存功能
- onTouchEvent用法解释以及触摸事件的传递机制
- android事件传递机制以及onInterceptTouchEvent()和onTouchEvent()详解二之小秘与领导的故事
- iOS 事件响应链详解(The Responder Chain)
- android事件传递机制以及onInterceptTouchEvent()和OnTouchEvent()详解三之ACTION_CANCEL事件和事件回传
- android事件传递机制以及onInterceptTouchEvent()和onTouchEvent()详解二之小秘与领导的故事
- android事件传递机制以及onInterceptTouchEvent()和onTouchEven
- Cocos-2d 关于SwallowTouch,进一步解释触摸事件分发机制
- android事件传递机制以及onInterceptTouchEvent()和OnTouchEvent()详解三之ACTION_CANCEL事件和事件回传