iOS中觸摸事件的傳遞和響應機制
所有繼承響應者對象UIResponder都能接收并處理事件。按照時間順序,先找到到最合適的view,然后就會調用view的touches方法,這些方法的默認做法是將事件順著響應這鏈條向上傳遞,將事件交由上一個響應者進行處理,直到有一個view能處理該響應為止或者丟棄。這是一個從上到下,再從下到上的過程。
1. 事件的產生
- 發生事件后,系統會將該事件加入到一個由UIApplication管理的事件隊列中。
- UIApplication會從事件隊列中取出最前面的事件,并將該事件分發下去處理。通常,先發送事件給應用程序的主窗口(keywindow)。
- keywindow會在視圖層次結構中找到一個最合適的視圖來處理事件。
2. 事件的傳遞
事件的傳遞先從父控件傳遞到子控件(UIApplication->window->尋找處理事件最合適的view)。
如果父view不能接受觸摸事件,那么子view也不能接收到觸摸事件。
2.1 如何找到最合適的view來處理事件
判斷keywindow自己是否接受事件
判斷事件是否在自己身上
子view數組中從后往前遍歷子控件,重復前面1,2步驟
如果沒有合適的子控件,那自己就是最合適的控件
2.2 尋找最合適的view底層剖析
有兩個重要的方法:
- hitTest:withEvent:
- pointInside:withEvent:
view會調用hitTest:withEvent:方法,hitTest:withEvent:方法底層會調用pointInside:withEvent:方法判斷觸摸點是不是在這個view的坐標系上。如果在坐標系上,會分發事件給這個view的子view。然后每個字view重復以上步驟,直至***層的一個合適的view。
3.事件的響應
事件響應會先從底層最合適的view開始,然后隨著上一步找到的鏈一層一層響應touch事件。默認touch事件會傳遞給上一層。如果到了viewcontroller的view,就會傳遞給viewcontroller。如果viewcontroller不能處理,就會傳遞給UIWindow。如果UIWindow無法處理,就會傳遞給UIApplication。如果UIApplication無法處理,就會傳遞給UIApplicationDelegate。如果UIApplicationDelegate不能處理,則會丟棄該事件。