最近的工作中發現基礎不太牢靠。需要好好鞏固一下關於iOS的事件響應的方式了。從最簡單的用戶用手指點擊了一下屏幕開始吧。
其實總結出來就是一句話:事件會從window的最下面的view向上傳遞尋找可以響應該事件的view,而找到響應的對象後,需要再向下尋找最終可以對這個事件作出處理的對象~
如果手指點擊了一下屏幕,那麼就會生成一個事件(UIEvent),並且這個事件會被放入由UIApplication管理的事件隊列中。UIApplication負責將這個事件進行分發。首先,這個事件會被分發給UIWindow。然後Window就會在自己所有的View中進行查找,找到最適合的相應該事件的那個view.這個過程中所有的view都會調用hitTest:WithEvent:方法。並且順序為從最底層的父view開始逐漸向最上層的subView進行尋找,知道找到最後的那個hitTest:WithEvent:返回YES且pointInside:WithEvent:為YES的子view。
而在window將事件傳遞給View之前,會檢查目前是否有UIGestureRecognizer相應該事件。如果有的話,則使用recognizer的target進行相應,而不再檢查所有的子view.
如果沒有recognizer,則找到了相應的view(這個view叫responder object)。這時候則會調用相應的響應的view的touches系列方法
touchesBegan:withEvent: touchesMoved:withEvent: touchesEnded:withEvent: touchesCancelled:withEvent:
這幾個方法的第一個參數為(NSSet *)touches, 第二個參數為(UIEvent *)event.
其中touches中所包含的元素均為UITouch類的對象。touches的count則為目前有多少個點在屏幕上進行觸摸。
UITouch類有以下5個屬性:
window :觸碰產生時所處的窗口,由於窗口可能發生變化,當前所在的窗口不一定是最開始的窗口。
view:觸碰產生時所處的視圖。由於視圖可能發生變化,當前視圖也不一定是最初的視圖。 tapCount:短時間內輕擊(tap)屏幕的次數,可根據tapCount判斷單擊、雙擊或更多的輕擊。 timeStamp:時間戳記錄了觸碰事件產生或變化時的時間。單位是秒。 phase:觸碰事件在屏幕上有一個周期,即觸碰開始、觸碰點移動、觸碰結束,中途取消。通過phase可以查看當前觸碰事件在一個周期中所處的狀態。UITouchPhase枚舉:UITouchPhaseBegan
UITouchPhaseMoved
UITouchPhaseStationary
UITouchPhaseEnded
UITouchPhaseCancelled
這時候,如果我們發現responder object無法處理該事件,則會沿著這個object的事件響應鏈進行向上傳遞,知道找到可以響應該事件的對象為止。
該文章參考如下三篇博客,對這三篇博客的作者表示感謝!
http://www.cnblogs.com/Quains/p/3369132.html
http://www.cnblogs.com/zhw511006/p/3517248.html
http://www.tuicool.com/articles/ZZJreu