事件的傳遞及相應者鏈條,事件傳遞鏈條
除去高大上的標題,本文主要就是講當你觸碰手機螢幕上任意點的時候,系統是怎樣找到那個需要響應該觸碰事件的控制項,以及該控制項對觸碰事件的響應情況
首先是 找到應該響應該觸碰事件控制項的過程:觸摸事件首先是被應用的訊息迴圈機制檢測到,加入到訊息佇列,到處理該訊息時,由application向下問window,window又去問rootcontroller(這個觸摸點在沒在你的view範圍中),rootcontroller又問自己的view,view又向下問自己的所有子控制項,進行篩選,
篩選的規則是:
1.自己是否能接收觸摸事件?2.觸摸點是否在自己身上?3.以上都滿足了就從後往前遍曆子控制項,重複前面的兩個步驟4.如果沒有合格子控制項,那麼就自己最適合處理這裡的“問”預設是通過控制項的- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent*)event方法一層一層從外往內掉用; 找到最後找到最適合處理該觸摸事件的控制項,該控制項預設會有對觸摸事件的處理:(以下就該是響應者鏈條的內容了)根據控制項對事件的預設響應情況,大概分三種(肯定不止):1.button:預設會處理響應該事件,並且不會再調用 [super touchesBegan:touches withEvent:event];向上拋響應,這樣該響應鏈條就斷了;2.uiview: 如果不實現uitouches方法,預設會調用父類(uiresponser)中的touches方法,該方法內部預設會自動把響應交給下一響應者處理;3.uiimageview:預設是不與使用者互動的,所以該控制項預設也就不會被選為最佳處理事件的控制項,所以該種類不應該算;如果控制項自己實現了touches方法來處理觸摸事件,並且響應完又調用了[super touchesBegan:touches withEvent:event];來讓下一響應者繼續響應,這樣一層一層由裡向外久構成了響應者鏈條; 需要說明的是:響應者不都必然是view等控制項,也可能是viewController等控制器(UIviewController也繼承於UIresponser);找下一響應者的原則是:1>如果當前這個view事控制器的view,那麼控制器就是上一個響應者(控制器也繼承了UIResponser,所有控制器也有touches……方法)2>如果當前這個view不是控制器的view,那麼父控制項就是上一個響應者 響應者鏈的事件傳遞過程:1.如果view的控制器存在,就傳遞給控制器;如果控制器不存在,則將其傳遞給它的父視圖2.在視圖階層的最頂級視圖,如果也不能處理收到的事件或訊息,則其將事件或訊息傳遞給window對象進行處理3.如果window對象也不處理,則其將事件或訊息傳遞給UIApplication對象4.如果UIApplication也不能處理該事件或訊息,則將其丟棄