iOS學習筆記之觸摸事件&UIResponder
觸摸事件
與觸摸事件相關的四個方法如下:
- 一根手指或多根手指觸摸螢幕
-(void)touchesBegan:(NSSet *)touches
withEvent:(UIEvent *)event;
- 一根手指或多根手指在螢幕上移動(随着手指的移動,相關的對象會持續發送該消息)
-(void)touchesMoved:(NSSet *)touches
withEvent:(UIEvent *)event;
- 一根手指或多根手指離開螢幕
-(void)touchesEnded:(NSSet *)touches
withEvent:(UIEvent *)event;
- 在觸摸操作正常結束之前,某個系統事件(例如有電話進來)打斷了觸摸過程
-(void)touchesCancelled:(NSSet *)touches
withEvent:(UIEvent *)event;
UITouch對象和事件相應方法的工作機制
- 一個UITouch對象對應螢幕上的一根手指。隻要手指沒有離開螢幕,相應的UITouch對象就會一直存在。這些UITouch對象都會儲存對應的手指在螢幕上的目前位置
- 在觸摸事件的持續過程中,無論發生什麼,最初發生觸摸事件的那個視圖都會在各個階段收到應用的觸摸事件消息。即使手指在移動時離開了這個視圖的frame區域,系統還是會向該視圖發送touchesMoved:withEvent:和touchesEnded:withEvent:消息。也就是說,當某個視圖發生觸摸事件後,該視圖将永遠“擁有”當時建立的所有UITouch對象。
- 自己編寫的代碼不需要也不應該保留任何UITouch對象。當某個UITouch對象的狀态發生改變時,系統會向指定的對象發送特定的事件消息,并傳入發生變化的UITouch對象
iOS在處理觸摸事件的機制和windows中的消息機制很相似。當某個應用發生觸摸事件後,系統都會将該事件添加到一個事件隊列裡,這個事件隊列是由UIApplication單例管理的。UIApplication會向“擁有”該事件的視圖發送特定的UIResponder消息,收到消息的視圖會進行進一步的處理。
多點觸摸
預設情況下,視圖在同一時刻隻能接收一個觸摸事件。如果一根手指已經出發了touchesBegan:withEvent:方法,那麼在手指離開螢幕之前(觸發touchesEnded:withEvent:方法之前),其他觸摸事件都會被忽略。為此,需要在接收觸摸事件的UIView的初始化方法中添加如下代碼,以允許多點觸摸
self.multipleTouchEnabled = YES;
響應對象鍊
UIResponder對象的子類對象除了UIView外,還包括UIViewController、UIWindow和UIApplication,這些對象能夠通過響應對象連結收事件。
UIResponder對象擁有一個名為nextResponder的指針,相關的UIResponder對象可以通過該指針組成一個響應對象鍊,如下圖所示
當UIView對象屬于某個UIViewController對象時,其nextResponder指針就會指向包含該視圖的UIViewController對象。當UIView對象不屬于任何UIViewController對象時,其nextResponder指針就會指向該視圖的父視圖。UIViewController對象的nextResponder指針通常會指向其視圖的父視圖。最頂層的父視圖是UIWindow對象,而UIWindow對象的nextResponder指向的是UIApplication單例。
如果沒有為某個UIResponder對象覆寫特定的事件處理方法,那麼該對象的nextResponder會嘗試處理相應的觸摸事件。事件會沿着響應對象鍊傳播,知道傳遞給UIApplication對象(響應對象鍊的最後一個對象),如果UIApplication也無法處理事件,系統就會丢棄該事件。