来自:https://www.jianshu.com/p/481465fc4f2d
事件分为3种:屏幕的、传感器的和外接设备。
事件触发时候的步骤分为:传递、响应。
传递: 从视图的层级root 到 最前面的的View 使用的的func为hittest,这个函数的意思就是检查当前的触摸点是不是在当前视图中。
是:
将触摸点转换为子视图在该视图的坐标系中,继续如上的试探。直到找到一个,立马停止接下来的试探。(子视图的寻找顺序是从 Index大的向小的进行)
否:结束在该View的事件传递,有则转为下一个同级View
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { if (self.hidden || !self.userInteractionEnabled || self.alpha < 0.01 || ![self pointInside:point withEvent:event] || ![self _isAnimatedUserInteractionEnabled]) { return nil; } else { for (UIView *subview in [self.subviews reverseObjectEnumerator]) { UIView *hitView = [subview hitTest:[subview convertPoint:point fromView:self] withEvent:event]; if (hitView) { return hitView; } } return self; } }
可以看到,最终没有子View的时候,返回的就是这个最顶层的View。
响应:
在得到这个事件传递的路径之后。就会由子向父传递。直到该View添加了响应手势的办法,或者实现如下方法:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event; - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event; - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event; - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;
事件就会在这里响应,停止向上传递。
新增事件之间的区别:
手势识别和View的接受触摸事件。如果手势识别成功,那么取消事件的继续传递。
target-action的 消息来响应。消息不是事件,不通过Responder Chain派发,不会走响应者链。 有一种情况:如果消息没有target,那么,会走响应者链,比如 editing menu的 cut: copy:等。
ps:操作就是 事件传递完毕,检查直到当前第一个实现了UIResponse的View,此时会调用touchBegin;接着再向后查找是否有手势;有的话就touchesCanceled,touch事件取消。手势响应;