實驗1:code
定義 BaseView,在裏面實現方法touchBegan,監聽當前哪一個類調用了該方法。對象
在控制器的界面上加5個顏色不一樣的view,每一個view自定義view去實現,所以在不一樣的view上的手勢就能夠由不一樣的view攔截到。事件
![UI效果圖](http://static.javashuo.com/static/loading.gif)
//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
響應者鏈條
![響應者鏈條](http://static.javashuo.com/static/loading.gif)
事件傳遞的完整過程
- 先將事件對象由上往下傳遞(父控件傳遞給子控件),找到最合適的控件來處理
- 調用最合適控件的touch方法
- 若是調用了[super touches...]方法就會將事件順着響應者鏈條向上傳遞,傳遞給上一個響應者
- 接着就會調用上一個響應者的touches...方法
事件響應者
如何判斷該控件的上一個響應者?
- 若是當前這個view是控制器的view,那麼上一個響應者就是控制器
- 若是當前這個view不是控制器的view,那麼上一個響應者就是父控件。
事件傳遞給UIApplication後若是不處理的話,該事件會銷燬掉。import
控制器view上的子控件的touch...方法若是子控件不處理那麼都會順着響應者鏈條向上傳遞給上一層響應者對象,好比能夠交給控制器處理。原理