1. 响应者对象(UIResponder)
学习触摸事件首先要了解一个比较重要的概念-响应者对象(UIResponder)。
在iOS中不是任何对象都能处理事件,只有继承了UIResponder的对象才能接受并处理事件,我们称之为“响应者对象”。
那么为什么继承自UIResponder的类就能够接收并处理事件呢?
因为UIResponder中提供了以下4个对象方法来处理触摸事件。
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
- (void)touchesEstimatedPropertiesUpdated:(NSSet<UITouch *> *)touches NS_AVAILABLE_IOS(9_1);
看下官方说明:意思就是responder要重载这四个方法,也可能会接收到其他的触摸,必须手动取消这些触摸保证正确的行为...语言功底太差,凑合看吧
// Generally, all responders which do custom touch handling should override all four of these methods.
// Your responder will receive either touchesEnded:withEvent: or touchesCancelled:withEvent: for each
// touch it is handling (those touches it received in touchesBegan:withEvent:).
// *** You must handle cancelled touches to ensure correct behavior in your application. Failure to
// do so is very likely to lead to incorrect behavior or crashes.
所以UIApplication、UIWindow、UIView都能接收触摸事件
2. 触摸事件
当用户点击屏幕后,UIApplication 先响应事件,然后传递给UIWindow。如果window可以响应。就开始遍历window的subviews。遍历的过程中,如果第一个遍历的view1可以响应,那就遍历这个view1的subviews(依次这样不停地查找,直至查找到合适的响应事件view)。如果view1不可以响应,那就开始对view2进行判断和子视图的遍历。依次类推view3,view4…… 如果最后没有找到合适的响应view,这个消息就会被抛弃。(整个遍历的过程就是树的先序遍历)。过程如下图:
参考链接:
https://www.jianshu.com/p/2e074db792ba
https://blog.csdn.net/hello_hwc/article/details/49176867
https://blog.csdn.net/mushaofeng1990/article/details/62434349