事件分发hitTest:withEvent: 、响应者链(Response Chain) 和 Gesture Recognizers(手势识别器) 联系。
事件传递之响应链(Event Delivery: The Responder Chain)【转】
内容里我添加了Gesture Recognizers 与 事件分发内容。应该比较全面。
涉及一下三张图:
一、 Gesture Reconnizers 和 hitTest:withEvent: 关系:
Gesture Recognizers在触摸事件处理流程中,处于观察者的角色,其不是view层级结构的一部分,所以也不参与responder chain。在将触摸事件发送给hit-test view之前,系统会先将触摸事件发送到hit-test view上绑定的或hit-test view父视图(superview)上绑定的Gesture Recognizers上。其流程大概如下图所示:
注:图中view与Gesture Recognizer的关系是,Gesture Recognizer关联在view或view的superview(可能多级)上。
二、hitTest:withEvent: 事件分发
iOS使用hit-testing寻找触摸的view。 Hit-Testing通过检查触摸点是否在关联的view边界内,如果在,则递归地(recursively)检查该view的所有子view。在层级上处于lowest(我理解就是离用户最近的view)且边界范围包含触摸点的view成为hit-test view。确定hit-test view后,它传递触摸事件给该view。
举例说明,假设用户触摸了图中的view E。iOS通过如下顺序查找hit-test view。
注: 假设上图中每个View 都可以接收事件,关于不可接收事件的条件请参看 上面详细文章(hidden 、alpha <0.0001、用户交互关闭、clipsToBounds、...)。 则hitTest 传递顺序
A--->B hitTest
|
C hitTest --->D hitTest
|
E hitTest
三、事件分发之Response Chain
Responder chain 序列在iOS确定一个事件并将它传递给initial object(通常是view)时开始。所以initial view有处理事件的第一个机会。下图描述了两个不同的事件传递路径(因为不同的app 设置)。一个App的事件传递路径由app特殊的构成决定,但事件传递路径会遵守相同的规则。
注: 关于Respnse chain 和 hitTest:withEvent: 关系,请参见文章详细。
事件分发(hitTest:withEvent: 和 Response)都是为了找到第一响应者first responder ,在 没有设置first responder 的情况下,
--------如果有设置first responder 则会直接将事件传递给 first responder 处理
Hit-test view是处理触摸事件的第一选择,如果hit-test view不能找到 first responder 或者 first responder 没有处理事件 那么该事件将从事件响应链中寻找响应器(在没有找到 first responder 的情况下,响应者链起始于你手指 触碰到的 view层级最高的 的view 。 往上传递到 UIApplaction 如果中间没有响应则 丢弃事件。 )。
上图可以看到hitTest 和 响应者链 方向相反。Respnse chain 它开始于第一个响应器终止于应用对象(application object)。