參考:http://www.javashuo.com/article/p-rigmnzyj-hm.html
先執(zhí)行事件鏈,找到合適的view,在執(zhí)行響應鏈。
一悬钳、事件鏈
UIApplication -> window -> view -> view ……..->view
a. 當iOS程序中發(fā)生觸摸事件后唆途,系統(tǒng)會將事件加入到UIApplication管理的一個任務隊列中
b. UIAplication 將處于任務隊列最前端的事件向下分發(fā)捕儒,即UIWindow
c. UIWindow 將事件向下分發(fā)板惑,即UIView
d. UIView首先看自己是否能處理事件(hidden = NO, userInteractionEnabled = YES, alpha >= 0.01),觸摸點是否在自己身上必指。如果能,那么繼續(xù)尋找子視圖
e. 遍歷子控件(從后往前遍歷)恕洲,重復上面的步驟塔橡。
f. 如果沒有找到,那么自己就是事件處理著,如果自己不能處理霜第,那就不做任何事
-
事件鏈的過程其實就是 - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
函數(shù)的執(zhí)行過程谱邪。
二、響應鏈
響應鏈是從最合適的view開始傳遞庶诡,處理事件傳遞給下一個響應者惦银,響應鏈的傳遞是個事件鏈傳遞相反的。如果所有響應者都不處理事件,則事件被丟棄扯俱。通常獲取級響應者是通過nextResponder方法的书蚪。
- 通常找到對應的view之后然后查找此view是否能處理此事件。
其實也就是看view能否依次響應下面的幾個方法(并不一定是全部)來構成一個消息迅栅。
- (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;
例如:
1.按鈕上添加手勢情況1
UIButton *btn = [UIButton buttonWithType:UIButtonTypeSystem];
[btn setTitle:@"按鈕" forState:UIControlStateNormal];
btn.frame = CGRectMake(40, 200, 50, 30);
btn.backgroundColor = [UIColor greenColor];
[self.view addSubview:btn];
[btn addTarget:self action:@selector(btnAction) forControlEvents:UIControlEventTouchUpInside];
UITapGestureRecognizer *tap1 = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction1)];
[btn addGestureRecognizer:tap1];
- (void)btnAction {
NSLog(@"按鈕點擊的");
}
- (void)tapAction1 {
NSLog(@"手勢1");
}
點擊按鈕后執(zhí)行的結果是:
手勢1
為什么呢殊校?
由于當我們添加了UITapGestureRecognizer手勢之后,當nextResponder為當前的viewcontroller時读存,它走touches的幾個方法時先構成了tap手勢的消息發(fā)送为流,因此打印的結果是手勢1
2.按鈕上添加手勢情況2
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panAction)];
[btn addGestureRecognizer: pan];
- (void)panAction {
NSLog(@"手勢");
}
給按鈕上添加的是平移手勢
當我們點擊按鈕時結果為
按鈕點擊的
當我們平移按鈕時結果為
手勢
3.按鈕上添加手勢情況3
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panAction)];
[btn addGestureRecognizer: pan];
UITapGestureRecognizer *tap1 = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction1)];
[btn addGestureRecognizer:tap1];
[btn addTarget:self action:@selector(btnAction1) forControlEvents:UIControlEventTouchDragInside];
- (void)tapAction {
NSLog(@"手勢");
}
- (void)tapAction1 {
NSLog(@"手勢1");
}
- (void)btnAction1 {
NSLog(@"按鈕點擊的1");
}
當按鈕的controlEvents為UIControlEventTouchDragInside時
,同時添加了平移和輕拍手勢
當我們點擊按鈕時執(zhí)行的是 輕拍手勢
手勢1
當我們平移按鈕時让簿,平移的手勢和按鈕的響應都執(zhí)行了
按鈕點擊的1
手勢