誰纔是最終響應者

1.基本概念:

  • UIEvent:當用戶觸摸屏幕時,UIKit會將這一操做封裝成一個個的UIEvent對象,該對象包含着一些處理事件所須要的信息
  • 響應者:在UIKit中,全部直接或者間接繼承UIResponder類的都具備響應事件的能力(例如:UIApplicationUIViewUIViewController和咱們自定義的視圖以及視圖控制器),這些對象一般都被稱爲響應對象(也稱爲響應者,hit-testview)
  • 響應鏈:在一個App中,全部視圖是按照樹狀結構進行組織的,除了根視圖外,每一個視圖都有一個父視圖,而每一個視圖均可以有0個或者多個子視圖,而在這個樹狀結構構建的同時,也構建了一條條的事件響應鏈

當用戶觸摸屏幕時會產生若干個UIEvent對象,UIKit會把UIEvent對象放到事件隊列中,當須要處理事件的時候,UIApplication會從事件隊列頭部取出一個UIEvent對象進行分發,找到能夠處理該事件的響應者git

2.尋找最終響應者過程

當手指觸摸屏幕的時候,UIApplication經過從事件隊列頭中取出一個事件對象分發給UIWindow,
而後每個視圖經過調用hitTest:withEvent和pointInside:withEvent方法,
如pointInside:withEvent方法返回YES,則繼續遍歷該視圖上的全部子視圖,
直到找到最終響應視圖,而後hitTest:withEvent方法逐級返回最終響應視圖,
找到最終響應視圖以後則會嘗試讓其處理這個事件,若是沒法處理該事件,
則事件會被傳遞給下一個事件處理者,直到傳遞到AppDelegate,則事件會被丟棄。
-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
/**當知足如下條件,返回視圖層級中能響應觸控點的最佳視圖
 self.hidden == NO;
 self.userInteractionEnabled = YES;
 self.alpha > 0.01;事件的觸摸點在視圖的bounds內
 */複製代碼

3.手勢識別器


當我給pupleView重寫了touchsBegan:withEvent、touchsEnded:withEvent、touchsMoved:withEvent、touchsCancelled:withEvent方法,而且給pupleView添加了UIGestureRecognizer並點擊,控制檯打印的結果以下:
github

控制檯打印的結果以下:
XLPupleView touchesBegan
XLPupleView touchesMoved
handle Tap複製代碼

說明:在識別一個觸摸事件的時候,若是該視圖有添加手勢識別器,則手勢識別器擁有更高優先級,優先處理事件。
其會先調用touchsBegan:withEvent、touchsMoved:withEvent方法和手勢識別器對應響應方法,只有手勢
識別失敗了,纔會觸發響應鏈中的touchsEnded:withEvent方法,若是識別成功,則會觸發touchsCancelled:withEvent
取消響應者鏈對觸摸事件的響應。
也能夠設置手勢識別器中的cancelsTouchesInView屬性,該屬性默認爲YES。
當設置爲NO時,手勢識別器識別到觸摸事件以後不會發送touchesCancelled:withEvent取消響應鏈對觸摸事件的響應,
這個時候手勢識別器和hit-testview均響應觸摸事件。複製代碼

Demo下載地址:github.com/hlc0000/Res…bash

今天就總結到這裏了,但願各位小夥伴多多提出寶貴意見,交流學習~
ide

相關文章
相關標籤/搜索