iOS基礎(chǔ)06—--事件響應(yīng)鏈
移動(dòng)應(yīng)用的最大特性就是響應(yīng)用戶交互操作,那么iOS系統(tǒng)是如何去響應(yīng)一個(gè)簡(jiǎn)單的點(diǎn)擊事件的呢艘款?系統(tǒng)如何精準(zhǔn)地定位一個(gè)事件的響應(yīng)者呢舶治?
首先一個(gè)事件產(chǎn)生后,系統(tǒng)會(huì)將其包裝成一個(gè)uievent和uitouch對(duì)象魂毁,然后傳給當(dāng)前的app郊艘!當(dāng)前app一級(jí)一級(jí)查找響應(yīng)者的規(guī)程就形成了一個(gè)事件響應(yīng)鏈荷科!
事件傳遞進(jìn)來(lái)時(shí)唯咬,uiapplication會(huì)將事件放置到隊(duì)列中,然后會(huì)從隊(duì)列中取出事件傳遞給keywindow畏浆!注意每一個(gè)view都含有以下兩個(gè)方法:
1胆胰、獲取到響應(yīng)事件的view,然后傳遞回去刻获;
[hittest:withevent:]
2蜀涨、判斷事件是否在當(dāng)前view的范圍里蝎毡!
[pointinside:withevent:]
具體的實(shí)現(xiàn)如下圖
https://app.yinxiang.com/shard/s67/res/e53a101b-5a01-4487-b508-9db36abe48ba/IMG_2792.PNG
widow會(huì)先查看點(diǎn)擊事件是否在自己的范圍內(nèi)厚柳,如果是,就會(huì)繼續(xù)查詢子視圖沐兵!如圖所示别垮,如果當(dāng)前視圖滿足要求就會(huì)繼續(xù)查找當(dāng)前視圖的子視圖,否則會(huì)查找同等級(jí)的兄弟視圖扎谎,依次類推碳想,直到查到為止。
舉個(gè)例子:
https://app.yinxiang.com/shard/s67/res/0e978485-a7fa-4444-b8ab-322a32a31475/IMG_2793.PNG
如果在viewTwo的非viewThree區(qū)域進(jìn)行一個(gè)點(diǎn)擊事件毁靶,則會(huì)在viewOne的pointInside方法中得到true胧奔,然后hit test就會(huì)繼續(xù)遍歷子視圖,viewTwo的pointInside方法也返回true预吆,所以還會(huì)繼續(xù)遍歷子視圖龙填,到了viewthree,pointinside方法返回false啡浊,所以最終的hit test就截止到viewTwo觅够,于是將viewTwo傳回去胶背,viewTwo就是最終的響應(yīng)者了巷嚣!
其次有個(gè)情況就是子視圖超過(guò)父視圖的范圍內(nèi)的點(diǎn)擊事件!如圖钳吟,在viewthree的非viewtwo的重疊區(qū)域進(jìn)行點(diǎn)擊事件廷粒,則響應(yīng)鏈在到viewtwo的pointinside那就被截?cái)嗔耍瑅iew two的hit test會(huì)返回nil红且,也就是說(shuō)找不到響應(yīng)者坝茎,事件不會(huì)被響應(yīng)!
那么這種情況怎么才能讓其進(jìn)行響應(yīng)呢暇番?這個(gè)時(shí)候必須得重寫hit test的實(shí)現(xiàn)才可以讓事件傳遞下去:
-(UIView )hitTest:(CGPoint)point withEvent:(UIEvent)event
{
UIView *view = [super hitTest:point withEvent:event];
if (view == nil) {
for (UIView *subView in self.subviews) {
CGPoint myPoint = [subViewconvertPoint:point fromView:self];
if (CGRectContainsPoint(subView.bounds, myPoint)) {
return subView;
}
}
}
return view;
}
另外不響應(yīng)事件還可能
- 是view被隱藏了hide嗤放,
- view不響應(yīng)了userinteractionenable=no;
- 透明度alpha<0.1
面試響應(yīng)鏈另一半:當(dāng)hitTest接收到能夠響應(yīng)事件的view后壁酬,window會(huì)將消息傳給UIApplication次酌,返回返回view就不做任何處理恨课。
兄弟view是先檢測(cè)第一個(gè)view還是檢測(cè)最后添加的view——推理應(yīng)該是檢測(cè)最后添加的view。