前言:
触摸事件是ios四种类型事件中最常运用到的,在学习触摸事件之前,先了解一下以下两个概念:UITouch对象和UIResponder响应对象链。
概述:
根据继承的关系图,我们知道UIView是UIResponder的一个子类,所以,在触摸屏幕(View)可以覆盖UIResponder包含的四种触摸方法,并各自处理四种不同的触摸事件。
1、一根手指或多根手指触摸屏幕
- (void)touchesBegan:(NSSet *)touches withEvent:(nullable UIEvent *)event;
每当系统检测到手指触摸屏幕事件后,就会创建UITouch对象。发生触摸的UIWiew对象会收到该方法消息,系统传入的第一个实参touches会包含所有相关的UITouch对象。
2、一根手指或多根手指在屏幕上移动(随着手指的移动,相关的对象会持续发送该消息)
- (void)touchesMoved:(NSSet *)touches withEvent:(nullable UIEvent *)event;
当手指在屏幕上移动时,系统会更新相应的UITouch对象,为其重新设置对应的手指在屏幕上的位置。最初发生触摸事件的那个UIView对象会收到该方法消息,系统传入的第一个实参touches会包含所有相关的UITouch对象,而且这些UITouch对象都是最初发生触摸事件时创建的。
3、一根手指或多根手指离开屏幕
- (void)touchesEnded:(NSSet *)touches withEvent:(nullable UIEvent *)event;
当手指离开屏幕时,系统会最后一次更新UITouch对象,为其重新设置对应的手指在屏幕上的位置。接着,最初发生触摸事件的UIView会收到该方法消息。当收到该消息的UIView执行完该方法后,系统就会释放和当前事件有关的UITouch对象。
4、在触摸操作正常结束前,某个系统事件(如有电话打进来)打断了触摸过程
- (void)touchesCancelled:(NSSet *)touches withEvent:(nullable UIEvent *)event;
在程序运行时,我们不免经常会遇到触摸被中断的情况,例如电量低提示弹窗、打进电话等,这些都是不由我们控制的,所以一般建议要实现touchesCancelled这个方法,一般情况下直接调用touchesEnd即可。
3D 触摸
- (void)touchesEstimatedPropertiesUpdated:(NSSet *)touches NS_AVAILABLE_IOS(9_1);
3D Touch相关方法,当前触摸对象估计的触摸特性,返回值是UITouchPropertyie
UITouch对象和事件响应方法工作机制归纳:
1、一个UITouch对象对应屏幕上的一根手指。只要手指没有离开屏幕,则UITouch对象就会一直存在,每个UITouch对象保存对应的手指在屏幕上到的位置
2、触摸移动的过程中,最初发生触摸的UIView都会在各个阶段接收到相应的触摸事件消息,即当某个UIView发生触摸事件后,该UIView将永远拥有当时创建的所有UITouch对象
3、当某个UITouch对象的状态发生变化时,系统会向指定的对象发生特定的事件消息,并传入发生变化的UITouch对象
当应用发生某个触摸事件后,系统会将该事件添加至一个由UIApplication实例管理的事件队列,由该实例分发队列中的事件。分发某个触摸事件时,该实例会向拥有该事件的UIView发送特定的UIResponder消息。当多根手指在同一视图、同一时刻,执行相同的触摸事件时,UIApplication实例会用单个消息、一次分发所有相关的UITouch对象。该实例在发送特定的UIResponder消息时,会传入一个NSSet对象。该对象将包含所有相关的UITouch对象(一个UITouch对象对应一根手指)。值得注意的是,因为UIApplication实例对“同一时刻”的判断很严格,所以通常情况下,哪怕一组事件都是在很短的一段时间内发生的,该实例也会发送多个UIResponder消息,分批发送UITouch对象。
响应对象链:
UIResponder对象可以接收触摸事件,UIView是UIResponder的一个子类,除此之外,UIResponder的子类还包括UIApplication、UIWindow、UIViewController。其中,UIViewController不是视图,既不能触摸也不能显示,UIViewController对象是通过响应对象链接收事件的。UIResponder对象拥有一个nextResponder指针,相关的UIResponder对象能通过nextResponder指针组成一个响应对象链,如图:
![](https://img.haomeiwen.com/i7465299/1acae1e6c20bc38a.png)
当UIView对象属于某个UIViewController对象时,其nextResponder指针就会指向包含该视图的UIViewController对象。当UIView对象不属于任何UIViewController对象时,其nextResponder指针就会指向该视图的父视图。UIViewController对象的nextResponder指针指向其父视图,顶层的父视图是UIWindow对象,UIWindow对象nextResponder指针指向UIApplication实例。
网友评论