事件传递和响应者链条原理分析

来源:互联网 发布:vb如何编写游戏 编辑:程序博客网 时间:2024/04/29 07:33

一、触摸事件的事件传递

       触摸事件的传递方向是 由内至外(外:指所触摸的最外层视图)

触摸开始后,系统会把事件加入到UIApplication事件队列。而后UIApplication会从事件队列中取出最前面的事件分发处理。先分发给程序的主窗口,让后主窗口调用

hitTest: withEvent:

方法,查找用户所点击的视图。

1.1、在最内层视图(key window 视图)上调用 pointInside:withEvent: 方法来判断事件触摸点是否在当前视图内。如果返回NO,则hitTest:withEvent: 方法返回nil,表明用户的触摸点不再此视图上。

1.2、如果返回YES,那么当前视图会向所有子视图发送hitTest:withEvent: 方法。

1.3、子视图仍然按照hitTest:withEvent: 和 pointInside:withEvent:结合的方法来查找所点击的视图。

1.4、如果最终都没有找到所点击的视图,则hitTest:withEvent:最后返回的仍然是nil。事件传递结束。

1.5、如果最终查找到所点击的视图,则hitTest:withEvent:最后返回的是所点击的视图对象。然后准备进行事件响应。


重要事例:当用户点击的point超出父视图(B)的frame时。程序最终找不到所点击的视图,hitTest:withEvent:返回是nil。

当程序查找到父视图(B)的时候,因为用户所点击的点处于父视图(B)的外面。pointInside:withEvent: 方法判断结果是触摸点不在此父视图(B)上,pointInside:withEvent: 方法返回的结果始终为NO,则父视图不会再向子视图发送hitTest:withEvent:方法。


二、触摸事件的响应者链条

       响应者链条的传递方向是 由外至内

2.1、事件传递查找到用户点击的视图(C)后,当前视图(C)是否能够响应触摸事件(处理触摸事件)。

2.2、如果不能响应触摸事件,则交给当前视图(C)的父视图来响应。

2.3、如果父视图不能响应触摸事件,则由父视图的父视图来响应。

2.4、若最后谁都不对此触摸事件做处理,则丢弃此事件。



一般来说,如果子视图响应了触摸事件后,父视图就不会再响应此触摸事件。

重要:

但是系统API判断子视图是否响应了触摸事件的方法。是由是否重写了

touchesBegan: withEvent:

方法来判断的。

如果您没有重写touchBegan:withEvent:方法,即使重写了剩余的其他三个touch方法,系统仍然认为子视图没有响应触摸事件而会一直向父视图响应下去。



1 0
原创粉丝点击