一.事件傳遞鏈
當(dāng)點(diǎn)擊一個(gè)按鈕的時(shí)候娱颊,事件如果傳遞到按鈕這個(gè)第一響應(yīng)者上拦耐,這就是事件傳遞鏈要做的事情弯蚜。系統(tǒng)根據(jù)下面兩個(gè)方法來(lái)傳遞事件十籍。
//該點(diǎn)是否在本視圖點(diǎn)擊范圍內(nèi) point已經(jīng)被轉(zhuǎn)換了成本視圖對(duì)應(yīng)frame- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event { //內(nèi)部實(shí)現(xiàn)大概是這樣
return CGRectContainsPoint(self.bounds, point);
}//本視圖/子視圖是否能夠傳遞本事件 point已經(jīng)被轉(zhuǎn)換了成本視圖對(duì)應(yīng)frame- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { //內(nèi)部實(shí)現(xiàn)大概是這樣
//用戶交互為NO,不處理
if(self.userInteractionEnabled == NO) { return nil;
} if([self pointInside:point withEvent:event]) { NSArray * superViews = self.subviews; //倒序從最上面的一個(gè)視圖開始查找
for (NSUInteger i = superViews.count; i > 0; i--) { UIView * subview = superViews[i - 1]; //轉(zhuǎn)換坐標(biāo)系 使坐標(biāo)基于子視圖
CGPoint newPoint = [self convertPoint:point toView:subview]; //得到子視圖 hitTest 方法返回的值
UIView * view = [subview hitTest:newPoint withEvent:event]; //如果子視圖返回一個(gè)view 就直接返回 不在繼續(xù)遍歷
if (view) { return view;
}
} //所有子視圖都沒(méi)有返回 則返回自身
return self;
} return nil;
}
當(dāng)點(diǎn)擊按鈕的時(shí)候唇礁,其實(shí)事件是這樣傳遞的:AppDelegate->UIApplication->UIWindow->xxx->UIViewController->UIView->UIButton勾栗。
二.事件響應(yīng)鏈
當(dāng)找到事件第一響應(yīng)者之后,該事件如何響應(yīng)盏筐,就是事件響應(yīng)鏈要做的事情围俘。
接著上面的例子,UIButton就是系統(tǒng)找出來(lái)的第一響應(yīng)者,那么會(huì)執(zhí)行如下方法:
//觸摸事件開始- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {}//觸摸事件移動(dòng)- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {}//觸摸事件結(jié)束- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {}//觸摸事件取消- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {}
如果你自己不處理界牡,你可以self.nextResponder讓下一個(gè)響應(yīng)者處理簿寂。
//觸摸事件開始- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { //讓下一個(gè)響應(yīng)者處理
[self.nextResponder touchesBegan:touches withEvent:event];
}
響應(yīng)者鏈也就是傳遞鏈的倒序。
- 這里需要注意的就是宿亡,如果給UIButton添加了target和UITapGestureRecognizer那么點(diǎn)擊按鈕只會(huì)執(zhí)行UITapGestureRecognizer常遂,也就是說(shuō)如果手勢(shì)和target同時(shí)滿足條件則只會(huì)執(zhí)行手勢(shì)。target也是touchesxxx中判定的挽荠,你可以重寫touchesxxx內(nèi)部實(shí)現(xiàn)為空克胳,你會(huì)發(fā)現(xiàn)并不影響手勢(shì)但會(huì)影響target。