事件分发(hitTest:withEvent: 、Response Chain) 与 GestureRecognizer

事件分发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)。

时间: 2024-11-01 02:01:58

事件分发(hitTest:withEvent: 、Response Chain) 与 GestureRecognizer的相关文章

消息点击事件的响应链---hitTest:withEvent:方法

*当用户点击屏幕时,会产生一个触摸事件,系统会将触摸事件加入到 UIApplication管理事件队里中 *UIApplication 会从事件队列中取出最前面的事件进行分发以便处理,通常,先发送事件给应用程序主窗口(UIwindow0 *主窗口会调用 hitTest:withEvent:方法在视图(UIView)层次结构中找到一个最合适的 UIView来处理触摸事件 (hitTest:LwithEvent:其实是 UIView 的一个方法UIWindow 继承自 UIView,因此主窗口UIW

事件分发机制Hit-Test View的应用(TabBar凸起不能点击解决方法)

一.事件分发原理 --- hitTest:withEvent:方法大致处理流程是这样的: 首先调用当前视图的pointInside:withEvent:方法判断触摸点是否在当前视图内: -- 若pointInside:withEvent:方法返回NO,说明触摸点不在当前视图内,则当前视图的hitTest:withEvent:返回nil -- 若pointInside:withEvent:方法返回YES,说明触摸点在当前视图内,则遍历当前视图的所有子视图(subviews),调用子视图的hitTe

Gesture Recognizers与触摸事件分发

一.Gesture Recognizers Gesture Recognizers是在iOS3.2引入的,可以用来识别手势.简化定制视图事件处理的对象.Gesture Recognizers的基类为UIGestureRecognizer,这一个抽象基类,定义了实现底层手势识别行为的编程接口.在UIKit框架中提供了6个具体的手势识别类,用来识别常见的手势.这6个手势识别器类为: UITapGestureRecognizer:用来识别点击手势,包括单击,双击,甚至三击等. UIPinchGestu

Gesture Recognizers与触摸事件分发[转]

一.Gesture Recognizers Gesture Recognizers是在iOS3.2引入的,可以用来识别手势.简化定制视图事件处理的对象.Gesture Recognizers的基类为UIGestureRecognizer,这一个抽象基类,定义了实现底层手势识别行为的编程接口.在UIKit框架中提供了6个具体的手势识别类,用来识别常见的手势.这6个手势识别器类为: UITapGestureRecognizer:用来识别点击手势,包括单击,双击,甚至三击等. UIPinchGestu

iOS事件分发

前段时间项目有一个需求,要在点击闪屏的时候做一些处理,刚接到这个需求觉得很简单啊,在原有的view上加个button或者手势识别啥的,后面实现的时候发现还是有点坑.无论我在闪屏上面加button还是手势都无法响应到touch事件,后来也想了很多种可能,比如是否消息传递到了其他视图,可最终发现确是我自己把button从父视图remove的时候把消息也给remove了,具体原因是闪屏显示完成的时候我把button也remove了,而同时显示闪屏的时候项目也做了很多初始化工作,很占用主线程,导致UIA

IOS 触摸事件分发机制详解

欢迎大家前往云+社区,获取更多腾讯海量技术实践干货哦~ 作者:MelonTeam 前言 很多时候大家都不关心IOS触摸事件的分发机制的实现原理,当遇到以下几种情形的时候你很可能抓破头皮都找不到解决方案: 某个点击消息由父视图来处理,子视图怎么把消息传递给父视图 这个按钮不灵敏,怎么扩大点击响应区域 怎么在一个页面处理手绘.表情拖动放缩.文本编辑三种消息 阅读本文,你会明白两个问题:IOS如何找到响应者.响应者是如何做出响应,明白这两个问题你就能解决类似上述的疑难杂症.通过控制Hit-test v

事件分发与响应者链

在iOS中事件分为三类: 触摸事件:通过触摸.手势进行触发(点击,缩放等) 运动事件:通过加速器进行触发(微信摇一摇等) 远程控制事件:通过其他远程设备触发(线控耳机) 只有继承自UIResponder的类才能处理事件 下面说一下触摸事件 当用户触摸屏幕时,事件会被封装成一个event实例,包含了触摸相关信息,然后操作系统对其进行分发,由响应者类进行处理(UIResponder的子类); 简单的分发与响应过程图: 1.事件的分发 iOS系统检测到手指触摸(Touch)操作时会将其放入当前活动Ap

事件分发&amp;响应链

iOS的三种事件:触摸事件/运动事件/远程控制事件 [objc] view plaincopy typedef enum { UIEventTypeTouches, UIEventTypeMotion, UIEventTypeRemoteControl, } UIEventType; 只有继承UIResponder类的对象才能处理事件,如UIView.UIViewController.UIApplication都继承自UIResponder,都能接收并处理事件.UIResponder中定义了上面

iOS学习9_事件分发&amp;响应链&amp;android转iOS的感悟

iOS的三种事件:触摸事件/运动事件/远程控制事件 typedef enum { UIEventTypeTouches, UIEventTypeMotion, UIEventTypeRemoteControl, } UIEventType; 只有继承UIResponder类的对象才能处理事件,如UIView.UIViewController.UIApplication都继承自UIResponder,都能接收并处理事件.UIResponder中定义了上面三类事件相关的处理方法: 下面主要讨论触摸事