IOS事件分發函數
咱們知道,若是要一個view(就是view,不是UIControl控件)可以響應事件操做,一般的作法是給該View加上相應的手勢,或者重寫和touch(固然也能夠是和motion相關的,但今天主要講的是touch)相關的一些方法,如:3d
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event對象
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event等blog
當用戶產生一個事件時,UIKIt會建立一個UIEvent的對象,這個對象就包含了一些相關的信息,而後它會將該UIEvent對象發送到事件隊列中,對於touch事件,則這個UIEvent對象是一系列的 touch。隊列
事件是會一直傳遞的,直到有對象能夠捕捉它,其傳遞流程是:UIApplication對象從事件隊列的頂部取得單個的事件對象,而後將其發送給UIWindow對象,而UIWindow對象則會一直向下傳遞,直到遇到能捕捉該事件的view。事件
某個View能不能捕捉該事件,主要看該View的下面函數的返回值,文檔
-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)eventit
這個是hit-Test機制,還有個響應鏈機制,不過系統有限使用hit-Test機制來進行事件分發,若是在這種狀況下事件沒能獲得處理,則會有第二次機會,系統使用響應鏈機制進行處理io
先看第一種: event
當事件傳遞到該View時,首先會調用該方法,而後根據該方法的返回值來肯定:
1. return [super hitTest:point withEvent:event]; 繼續傳遞
2. return self; 本身能捕捉就捕捉,而且結束事件傳遞
3. return nil; 本身不捕捉,也不傳遞事件
對於這個函數的解釋,感受官網的文檔寫的也不是很清楚,在下面我會繼續分析的。
先來看看事件究竟是怎樣被捕捉的(默認的狀況下,呵呵,爲何是默認的狀況下呢?別忘了 上面說的那個函數,它但是能夠改變傳遞的哦)
先看看圖:
1.若是touch事件在view A中,他會去檢查view B和view C
2.若是touch事件再也不view B中,而在view C中,則view C會向下去檢查其子view ----D和 E
3.若是touch事件不在view D中,而在view E中,則view E是這最終的View,他將接收這個事件,若是他不能進行響應,也就是沒有任何事件操做的函數存在,那該事件就會依次向上傳遞(具體怎麼傳 ,下面會講到),但這裏要注意了:若是這個view E 是個UIControl,例如Button,此時他又沒有增長點擊事件的話,則該事件消失掉,不會有第二次機會經過響應鏈反傳。
官網詳細寫道:若是事件經過hitTest的方式沒有獲得響應,則會得到第二次機會,經過下面的響應鏈進行反傳,直到該事件被捕捉
先來看一下事件的響應鏈:
圖:
先看左邊的圖:
1。Initial view 企圖捕捉事件或消息,若是它不能捕獲該事件,則它會把事件傳遞給superview,由於initail view不是它所在的view層級中最頂端的view
2.superview 企圖捕捉事件,若是它也不能捕獲,則它會把事件傳給它的superview,由於它也不是它所在view層級中最頂端的view
3.在某個controller的view層級中,topmost view(最頂端的view )企圖捕捉事件,若是它也不能捕獲事件,則把事件傳遞給 view controller
4.view controller 企圖捕捉事件,若是它不能捕捉,則把事件傳遞給UIWindow
5.UIWindow 企圖捕捉事件,若是不能捕獲,則它會把事件傳遞給UIApplication對象
6.若是UIApplication也不捕捉事件,則該事件被拋棄
再來看右邊的圖,雖然路徑有點不一樣,但全部的事件分發都遵循下面的格則:
1.某個 view把事件在它所在的view controller的view層級中向上傳遞,直到到達該view層級的最頂端的view
2.最頂端的view把事件傳遞到 view controller
3.view controller 再把事件傳遞給它的topmost view (最頂端的view)的superview,,,而後重複1——3步驟,直到到達這root view controller
4.root view controller 把事件傳遞給UIWindow
5.UIWindow把事件傳遞給UIApplication
好了,最後結合hit-Test機制和響應鏈機制來來分析下
1. hit-Test機制 return [super hitTest:point withEvent:event]; 繼續傳遞 ------傳遞到最後,若是事件能被捕捉,則事件分發結束,若是不能處理該事件,則會經過響應鏈進行反傳
2. hit-Test return self; 本身能捕捉就捕捉 ,而且結束事件傳遞 ------ 事件傳遞到該view 後,若是該view能捕捉該事件,則本身處理,事件到此結束,若是本身不能處理,則經過響應鏈進行反傳
3. return nil; 本身不捕捉,也不傳遞事件 --------事件傳遞到該view 後,馬上經過響應鏈進行反傳
肚子的墨水吐的也差很少了,更高深也講不出來了。。
但願大牛們 指導。。指導啊 !!!!