实验1:code
定义 BaseView,在里面实现方法touchBegan,监听当前哪一个类调用了该方法。对象
在控制器的界面上加5个颜色不一样的view,每一个view自定义view去实现,所以在不一样的view上的手势就能够由不一样的view拦截到。事件

//BaseView
#import "BaseView.h"
@implementation BaseView
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
NSLog(@"%@",[self class]);
}
结果:点击不一样的View打印出不一样的类名。it
结论:io
- 触摸事件是从父控件传递到子控件的。
- 点击了绿色(图上的2级)的view:UIApplication-> UIWindow -> UIViewController的view -> 绿色的view
- 点击了蓝色(图上的3级)的view:UIApplication-> UIWindow -> UIViewController的view -> 红棕色的view -> 蓝色的view
- 点击了黄色(图上的4级)的view:UIApplication -> UIWindow -> UIViewController的view -> 红棕色的view -> 蓝色的view -> 黄色的view
注意:若是父控件不能接收触摸事件,那么这个父控件的子控件也不能接收触摸事件event
如何找到最合适的控件来接收触摸事件?
- 本身可否接收触摸事件?
- 触摸点是否在本身身上?
- 从后往前遍历子控件,重复前面2个步骤
- 若是没有符合条件的子控件,那么就本身最适合处理
事件响应原理
产生的touch方法的默认作法是将事件顺着响应者链条向上传递,将事件交给上一个响应者处理。class
响应者链条

事件传递的完整过程
- 先将事件对象由上往下传递(父控件传递给子控件),找到最合适的控件来处理
- 调用最合适控件的touch方法
- 若是调用了[super touches...]方法就会将事件顺着响应者链条向上传递,传递给上一个响应者
- 接着就会调用上一个响应者的touches...方法
事件响应者
如何判断该控件的上一个响应者?
- 若是当前这个view是控制器的view,那么上一个响应者就是控制器
- 若是当前这个view不是控制器的view,那么上一个响应者就是父控件。
事件传递给UIApplication后若是不处理的话,该事件会销毁掉。import
控制器view上的子控件的touch...方法若是子控件不处理那么都会顺着响应者链条向上传递给上一层响应者对象,好比能够交给控制器处理。原理