響應(yīng)者鏈?
響應(yīng)者鏈條概念:iOS系統(tǒng)檢測到手指觸摸(Touch)操作時會將其打包成一個UIEvent對象,并放入當前活動Application的事件隊列,單例的UIApplication會從事件隊列中取出觸摸事件并傳遞給單例的UIWindow來處理,UIWindow對象首先會使用hitTest:withEvent:方法尋找此次Touch操作初始點所在的視圖(View),即需要將觸摸事件傳遞給其處理的視圖,這個過程稱之為hit-test view。
當一個點擊touch事件發(fā)生時, 設(shè)備首先會先找到touch發(fā)生的視圖:??
執(zhí)行順序:??
1. 設(shè)備將手指觸摸UITouch 和 事件UIEvent對象打包, 放到當前活動的Application的事件列表中?
2. 單例的UIApplication會從事件隊列中取出觸摸事件并傳遞給單例UIWindow?
3. UIWindow使用hitTest:withEvent:方法查找touch操作的所在的視圖view
查找方法: (從UIWindow開始->viewController->...->hit-test view)UIWindow實例對象會首先在它的內(nèi)容視圖上調(diào)用`hitTest:withEvent:`,此方法會在其視圖層級結(jié)構(gòu)中的每個視圖上調(diào)用`pointInside:withEvent:`(該方法用來判斷點擊事件發(fā)生的位置是否處于當前視圖范圍內(nèi),以確定用戶是不是點擊了當前視圖),如果pointInside:withEvent:返回YES,則向當前視圖的所有子視圖(subviews)發(fā)送hitTest:withEvent:消息,直到找到touch操作發(fā)生的位置,這個視圖也就是要找的hit-test view。
上面找到了事件的第一響應(yīng)者,接下來就該沿著尋找第一響應(yīng)者的相反順序來處理這個事件,如果UIWindow單例和UIApplication都無法處理這一事件,則該事件會被丟棄。
- touchBegan事件判斷點擊的位置在View上還是在View的子View上
-?(void)touchesBegan:(NSSet?*)touches?withEvent:(UIEvent?*)event
說明:??
1、如果最終 hit-test沒有找到第一響應(yīng)者,或者第一響應(yīng)者沒有處理該事件,則該事件會沿著響應(yīng)者鏈向上回溯,如果UIWindow實例和UIApplication實例都不能處理該事件,則該事件會被丟棄;
2、hitTest:withEvent:方法將會忽略
2.1 隱藏(hidden=YES)的視圖
2.2 禁止用戶操作(userInteractionEnabled=NO)的視圖
2.3 alpha級別小于0.01(alpha < 0.01)的視圖
2.4 如果一個子視圖的區(qū)域超過父視圖的bound區(qū)域(父視圖的clipsToBounds屬性為NO,這樣超過父視圖bound區(qū)域的子視圖內(nèi)容也會顯示),那么正常情況下對子視圖在父視圖之外區(qū)域的觸摸操作不會被識別,因為父視圖的pointInside:withEvent:方法會返回NO,這樣就不會繼續(xù)向下遍歷子視圖了。當然,也可以重寫pointInside:withEvent:方法來處理這種情況。