1.什么是UIEvent
UIEvent代表iOS系統(tǒng)中的一個事件躯肌,可以分為三類:UIEventTypeTouches觸摸事件者春、UIEventTypeMotion運動事件、UIEventTypeRemoteControl遠程事件清女。
UIEventTypeTouches觸摸事件钱烟,通過點擊,拖拽,縮放等等觸發(fā)拴袭。
UIEventTypeMotion運動事件传惠,通過搖晃屏幕等觸發(fā)。
UIEventTypeRemoteControl通過遠程事件控制稻扬,或者耳機等觸發(fā)。
UIEvent繼承于NSObject.
2.什么是UIResponder
在iOS當中羊瘩,只有繼承自UIResponder的類才能處理各種事件泰佳。
我們常用的UIView、UIViewController尘吗、UIApplication都繼承自UIResponder逝她,它們都能接收并處理事件。
@interface UIView : UIResponder<NSCoding, UIAppearance, UIAppearanceContainer, UIDynamicItem, UITraitEnvironment, UICoordinateSpace, UIFocusEnvironment>
UIResponder中提供了處理上述三種UIEvent的方法睬捶,根據(jù)事件的類型有不同的處理方法黔宛。
3.什么是UITouch
當用戶的一根手指觸摸屏幕的時候會創(chuàng)建一個對應的UITouch,這個UITouch會記錄手指運動的信息擒贸,比如說位置臀晃,時間,階段等等介劫。手指在屏幕的時候系統(tǒng)會更新同一個UITouch對象徽惋,如果手指離開了屏幕,這個UITouch對象就被銷毀了座韵。
我們可以發(fā)現(xiàn)處理點擊事件的方法里有兩個參數(shù)险绘。
- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
??:一次完整的觸摸事件只會產(chǎn)生一個UIEvent對象,也就是說不管手指在屏幕上怎么移動都是一個UIEvent對象誉碴。
而touches這個NSSet里面宦棺,裝著的是UITouch對象,從這個里面可以看出是單點觸摸還是多點觸摸黔帕。也就是說兩個手指同時觸摸屏幕代咸,那么touches里就有兩個UITouch對象。
4.Gesture Recognizer
??:如果有事件到來時成黄,視圖有附加的手勢識別器侣背,則手勢識別器優(yōu)先處理事件。如果手勢識別器沒有處理事件慨默,則將事件交給視圖處理贩耐,視圖如果未處理則順著響應者鏈繼續(xù)向后傳遞。
也就是說手勢識別器的優(yōu)先級高于事件處理厦取。如果手勢在事件響應鏈中潮太,那么手勢會把這個響應鏈打斷。
????:比如說現(xiàn)在有兩個view,viewb在viewa的上面铡买,兩個view都添加了手勢更鲁,那么我們點擊viewa的時候可以響應,但是點擊viewb的時候就沒有響應了奇钞,這就是因為viewa上添加了手勢打斷了響應鏈澡为,所以viewb響應不到這個點擊事件了。
5.UIControl
UIControl對于事件的處理會打破上面的規(guī)則景埃。
????:比如在viewa上添加了一個button媒至,給這個button和這個views都添加了手勢,那么views和button的手勢都可以響應谷徙。因為UIButton繼承于UIControl拒啰,也就是說如果UIButton是第一響應者,他的事件是由UIApplication直接派發(fā)的完慧,不通過響應鏈傳遞谋旦,如果不能處理再交給響應鏈。
而如果是剛才那種情況屈尼,給UIButton addTarget的話册着,這個target是不會被響應的。
所以說這個action會因為父類的響應鏈被打斷而無法執(zhí)行脾歧,而gesture不會因為父類的響應鏈被打斷而無法執(zhí)行指蚜。
6.事件響應邏輯
當事件到來時,會通過hitTest和pointInside兩個方法涨椒,從Window開始向上面的視圖查找摊鸡,找到第一響應者的視圖。找到第一響應者后蚕冬,系統(tǒng)會判斷其是繼承自UIControl還是UIResponder免猾,如果是繼承自UIControl,則直接通過UIApplication直接向其派發(fā)消息囤热,并且不再向響應者鏈派發(fā)消息猎提。
如果是繼承自UIResponder的類,則調(diào)用第一響應者的touchesBegin旁蔼,并且不會立即執(zhí)行touchesEnded锨苏,而是調(diào)用之后順著響應者鏈向后查找。如果在查找過程中棺聊,發(fā)現(xiàn)響應者鏈中有的視圖添加了手勢伞租,則進入手勢的代理方法中,如果代理方法返回可以響應這個事件限佩,則將第一響應者的事件取消葵诈,并調(diào)用其touchesCanceled方法份帐,然后由手勢來響應事件辐啄。
如果手勢不能處理事件焕参,則交給第一響應者來處理霞势。如果第一響應者也不能響應事件,則順著響應者鏈繼續(xù)向后查找泞坦,直到找到能夠處理事件的UIResponder對象窖贤。如果找到UIApplication還沒有對象響應事件的話,則將這次事件丟棄贰锁。