最近的工作中发现基础不太牢靠。需要好好巩固一下关于iOS的事件响应的方式了。从最简单的用户用手指点击了一下屏幕开始吧。
其实总结出来就是一句话:事件会从window的最下面的view向上传递寻找可以响应该事件的view,而找到响应的对象后,需要再向下寻找最终可以对这个事件作出处理的对象~
如果手指点击了一下屏幕,那么就会生成一个事件(UIEvent),并且这个事件会被放入由UIApplication管理的事件队列中。UIApplication负责将这个事件进行分发。首先,这个事件会被分发给UIWindow。然后Window就会在自己所有的View中进行查找,找到最适合的相应该事件的那个view.这个过程中所有的view都会调用hitTest:WithEvent:方法。并且顺序为从最底层的父view开始逐渐向最上层的subView进行寻找,知道找到最后的那个hitTest:WithEvent:返回YES且pointInside:WithEvent:为YES的子view。
而在window将事件传递给View之前,会检查目前是否有UIGestureRecognizer相应该事件。如果有的话,则使用recognizer的target进行相应,而不再检查所有的子view.
如果没有recognizer,则找到了相应的view(这个view叫responder object)。这时候则会调用相应的响应的view的touches系列方法
touchesBegan:withEvent: touchesMoved:withEvent: touchesEnded:withEvent: touchesCancelled:withEvent:
这几个方法的第一个参数为(NSSet *)touches, 第二个参数为(UIEvent *)event.
其中touches中所包含的元素均为UITouch类的对象。touches的count则为目前有多少个点在屏幕上进行触摸。
UITouch类有以下5个属性:
window :触碰产生时所处的窗口,由于窗口可能发生变化,当前所在的窗口不一定是最开始的窗口。
view:触碰产生时所处的视图。由于视图可能发生变化,当前视图也不一定是最初的视图。
tapCount:短时间内轻击(tap)屏幕的次数,可根据tapCount判断单击、双击或更多的轻击。
timeStamp:时间戳记录了触碰事件产生或变化时的时间。单位是秒。
phase:触碰事件在屏幕上有一个周期,即触碰开始、触碰点移动、触碰结束,中途取消。通过phase可以查看当前触碰事件在一个周期中所处的状态。UITouchPhase枚举:
UITouchPhaseBegan
UITouchPhaseMoved
UITouchPhaseStationary
UITouchPhaseEnded
UITouchPhaseCancelled
这时候,如果我们发现responder object无法处理该事件,则会沿着这个object的事件响应链进行向上传递,知道找到可以响应该事件的对象为止。
该文章参考如下三篇博客,对这三篇博客的作者表示感谢!
http://www.cnblogs.com/Quains/p/3369132.html
http://www.cnblogs.com/zhw511006/p/3517248.html
http://www.tuicool.com/articles/ZZJreu