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