IOS事件分发、Responder Chain(一)——hit-testing

原创 2015年11月17日 23:20:38

在IOS系统中,用户会触发若干事件,系统会分发这些事件,并交由恰当的对象来处理。IOS事件分发流程大致如下:

1、用户触发事件,系统将事件封装为event object对象,放入当前APP的event queue中。(touch事件对应的event object包含了一系列的touch对象,而motion对应的event则因事件不同而不同)

2、由当前APP对应的单例对象UIApplication在queue头中取出event object,分发至当前APP的主window object

3、主window object会将event object分发至当前最合适的initial object来处理。(对于touch event,initial object为hit-test view, 对于motion,remote control,initial object为first responder)

4、当然initial object也可以不处理该event,这样,event object会沿着一条规定的路径一路向上传递直到有object可以处理该event,或者抛弃该event。而这个向上寻找对应的处理event的object的路径,叫做Responder Chian。它始于initial object,终于application object。该chain上的所有对象,均继承与UIResponder,通过nextResponder方法,可以找到当前对象响应链上的下一个对象。

hit-testing 与 hit-test view

如前所述,当主window对象分发event object时,若event object为touch event,则最终hit-test view获得最先响应touch事件权利,而判断hit-test view的过程,叫做hit-testing。

hit-testing是一个递归的过程,执行过程如下

1、判断touch point是否在当前view中

2、若在,这继续判断touch point是否在当前view的子view中,若不在,则直接返回,不在继续判断。

3、这样一直递归判断,直到touch point所在的最底层的subview,并返回该subview作为响应touch event的hit-test view。

4、确定了hit-test view,系统将会使touch event交由该view处理,若该view没有处理该事件,则touch event会沿着Responder Chain一路向上寻找可以响应touch event的Responder。


在hit-testing中,系统会调用每个view的hitTest:withEvent: 方法,该方法最终会返回一个view作为hit-test view。而在hitTest:withEvent: 方法中,view又会调用 pointInside:withEvent:来测试当前view是否在touch的范围内,若是,则 pointInside:withEvent:返回YES,系统继续依次调用subview们的hitTest:withEvent: 方法,若pointInside:withEvent:返回NO,则hitTest:withEvent: 直接返回nil。


注意到hitTest:withEvent: 上面的这种实现,那么有一种情况是当subview的范围超出父view时,若touch是发生在超出的那块区域,则subview默认不会得到响应touch event的机会,因为在其父view判断 pointInside:withEvent:就已经返回了NO,hitTest:withEvent: 不会继续向下判断。


Apple网站上的这么一段说明,很好的解释了hit-testing的过程:

To illustrate, suppose that the user touches view E in Figure 2-1. iOS finds the hit-test view by checking the subviews in this order:

  1. The touch is within the bounds of view A, so it checks subviews B and C.

  2. The touch is not within the bounds of view B, but it’s within the bounds of view C, so it checks subviews D and E.

  3. The touch is not within the bounds of view D, but it’s within the bounds of view E.

    View E is the lowest view in the view hierarchy that contains the touch, so it becomes the hit-test view.

Figure 2-1  Hit-testing returns the subview that was touched



了解了上面hit-testing的判断过程,下面就有一个有趣的问题:

如图,绿色的view是红色view的subview,那么当我在蓝点所示的位置点击屏幕时,绿色view是否能够获取到该事件呢?

答案是否定的,因为系统在进行hit-testing时,会首先判断事件发生的point是否在其父view,即红色view范围内。很明显,point并不在红色view中,因此系统就放弃了继续判断其绿色子view是否在事件范围内。若想使得sub view一定要有所相应,那么应该设置父view的

clipsToBounds属性为YES,强制子view在父view的范围内显示。


参考资料

https://developer.apple.com/library/prerelease/ios/documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/event_delivery_responder_chain/event_delivery_responder_chain.html#//apple_ref/doc/uid/TP40009541-CH4-SW4

iOS:事件处理机制(二)--事件传递,Responder Chain响应链

事件传递         如上图,iOS中事件传递首先从App(UIApplication)开始,接着传递到Window(UIWindow),在接着往下传递到View之前,Window会将事件交给G...
  • houseq
  • houseq
  • 2014年10月20日 17:15
  • 3106

iOS 事件响应链详解(The Responder Chain)

原创Blog,转载请注明出处 http://blog.csdn.net/hello_hwc?viewmode=list 我的stackoverflow前言:在iOS编程中,经常会有复杂的时间v...
  • Hello_Hwc
  • Hello_Hwc
  • 2015年10月16日 12:17
  • 4048

iOS事件分发机制(一) hit-Testing

iOS中的事件大概分为三种,分别是 Milti-Touch Events, Motion Events 和Remote Control Events(events for controlling mu...
  • yeyuwuhen1203
  • yeyuwuhen1203
  • 2016年03月24日 13:45
  • 263

iOS事件分发机制(一) hit-Testing

http://suenblog.duapp.com/blog/100031/iOS%E4%BA%8B%E4%BB%B6%E5%88%86%E5%8F%91%E6%9C%BA%E5%88%B6%EF%B...
  • jeffasd
  • jeffasd
  • 2016年02月15日 18:26
  • 372

iOS事件响应链(Responder Chain)

概述 在iOS中,视图的层级一般都是 父视图->添加各种子视图。这时候某个视图(子视图)上有个按钮,需要我们交互。但是有时候我们会发现无论如何都没有反应。这时候可能就是我们对iOS的事件传递响应还...
  • guaishushu1ss
  • guaishushu1ss
  • 2017年08月04日 20:18
  • 109

iOS的事件分发

移动平台
  • sakulafly
  • sakulafly
  • 2014年01月25日 20:29
  • 8005

iOS事件的分发机制和响应者链(Swift)

当我们在设计自己的APP时,可能会想动态的响应事件.例如:屏幕上许多对象都能够发生触摸,我们必须决定哪一个对象来响应给定的事件并且知道对象是如何接受事件的。当用户事件产生的时候,UIKit会创建一个事...
  • longshihua
  • longshihua
  • 2016年07月19日 10:48
  • 2590

事件分发机制的再整理

分析的对象为:MotionEvent;         三个很重要的方法:dispatchonTouchEvent()(事件分发)、onInterceptTouchEVent()(事件拦截)、onTo...
  • zjngogo
  • zjngogo
  • 2016年03月16日 20:21
  • 1294

响应者链(Responder Chain)

响应者链(Responder Chain) 响应者对象(Responder Object),指的是有响应和处理事件能力的对象。响应者链就是由一系列的响应者对象构成的一个层次结构。 UIRespon...
  • bravegogo
  • bravegogo
  • 2016年04月18日 13:14
  • 136

Android事件分发机制完全解析,带你从源码的角度彻底理解(上)

其实我一直准备写一篇关于Android事件分发机制的文章,从我的第一篇博客开始,就零零散散在好多地方使用到了Android事件分发的知识。也有好多朋友问过我各种问题,比如:onTouch和onTouc...
  • sinyu890807
  • sinyu890807
  • 2013年06月20日 08:30
  • 320140
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:IOS事件分发、Responder Chain(一)——hit-testing
举报原因:
原因补充:

(最多只允许输入30个字)