響應者鏈
只要繼承了UIResponder的對象就可作爲事件的響應者,實際上UIControl繼承了UIView,UIView又繼承了UIResponder,由此可見,所有的對象都可作爲事件的響應者。
當用戶與某個控件交互時,該控件作爲“第一響應者”,第一響應者作爲響應者鏈的開始,該事件首先被髮送給第一響應者。事件將沿着響應者鏈一直向下傳播,直到被某個響應者處理。
通常來說,第一響應者都是UIView控件或UIView子類控件,當用戶觸摸該控件後,事件最先由該控件本身處理;如果該控件自身不處理時間,時間就會傳播到它對應的視圖控制器;如果視圖控制器不處理該事件,事件就會傳播到它對應的父視圖控制器……直到頂層視圖對應的視圖控制器。
典型響應者鏈傳播路線如下:
First Responder → FirstResponder的視圖控制器 → 父容器 → 父容器的視圖控制器→ UIWindow → UIApplication → 應用程序委託對象
如果某個事件經過上面完整的傳播過程,依然沒有被處理,那麼該事件就會被丟棄。一般來說,上面響應者鏈的任何響應者處理該事件,該事件就會停止傳播。
如果某個響應者“截獲”了某個事件,那麼該響應者要根據條件決定是否處理該事件。當響應者無法處理該事件時,則需要再處理方法中手動傳力該事件。
響應觸碰方法
如果希望自定義控件可以響應用戶的觸碰事件,則可以通過UIResPonder的如下4個方法實現:
(1) -touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event:當用戶手指開始接觸控件或窗口時激發該方法。
(2) -touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event:當用戶手指在控件上移動時激發該方法。
(3) -touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event:當用戶手指結束觸碰控件時激發該方法。
(4) -touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event:當系統事件終止了觸碰事件時激發該方法。
重寫這些觸碰事件處理方法時,第一個NSSet類型的參數代表了用戶同時觸碰控件的多個手指。
UITouch對象代表一個觸碰事件,該對象提供了一個tapCount屬性,該屬性用於返回用戶觸碰屏幕的次數。
至於獲取UITouch事件之後程序應該針對觸碰事件進行何種處理,則完全取決於用戶需要。
除此之外,iOS爲手指觸碰事件提供了手勢處理器,通過手勢處理器可使用一致的變成模式來處理各種觸碰事件,而且變成更加簡單,因此一般推薦用戶使用手勢處理器來處理用戶觸碰事件。
使用手勢處理器
通過手勢處理器處理用戶觸碰事件更加簡單,而且無論處理那種觸碰手勢,都可面向UIGestureRecognizer編程,其子類如下:
(1) UITapGestureRecognizer:處理用戶點擊手勢的手勢處理器。
(2) UIPinchGestureRecognizer:處理用戶捏合手勢的手勢處理器。
(3) UIRotationGestureRecognizer:處理用戶旋轉手勢的手勢處理器。
(4) UISwipeGestureRecognizer:處理用戶活動手勢的手勢處理器。
(5) UIPanGestureRecognizer:處理用戶拖動手勢的手勢處理器。
(6) UILongPressGestureRecognizer:處理用戶長按的手勢處理器。
使用手勢處理器用戶觸碰手勢的編程步驟如下:
(1) 根據程序要處理的手勢創建對應的手勢處理對象。
(2) 如果該UI控制不允許用戶交互,則將該控件的userInteracionEnabled屬性設爲YES,如果支持多點觸碰,則還需將multipleTouchEnabled設爲YES。
(3) 調用UI控件的addGestureRecognizer:方法添加手勢處理器。
使用UITapGestureRecognizer處理點擊手勢
UITapGestureRecognizer還提供了兩個屬性:
(1) numberOfTapsRequired:指定該手勢處理器只處理幾次觸碰事件。
(2) numberOfTouchesRequired:指定該手勢處理器只處理幾個手指的觸碰事件。
使用UIPinchGestureRecognizer處理捏合手勢
在用戶使用兩個手指在屏幕上捏合的過程中,程序可通過UIPinchGestureRecognizer檢測到用戶的這種捏合手勢。
使用UIPinchGestureRecognizer步驟與UITapGestureRecognizer相同,定義瞭如下兩個屬性獲取捏合相關信息:
(1) scale:獲取捏合比例。
(2) velocity:獲取捏合的速度。
使用UIRotationGestureRecognizer處理旋轉手勢
如果用戶使用兩個手指在屏幕上旋轉,程序可通過UIRotationGestureRecognizer檢測到用戶的這種旋轉手勢。
使用UIRotationGestureRecognizer處理手勢的步驟與使用其他手勢處理器的步驟完全相同。UIRotationGestureRecognizer定義瞭如下兩個屬性來獲取旋轉相關信息:
(1) rotation:獲取旋轉角度。
(2) velovity:獲取旋轉速度。
使用UISwipeGestureRecognizer處理輕掃手勢
當用戶使用一個或多個手指快速“掃”過屏幕時,程序可通過UISwipeGestureRecognizer檢測到用戶的這種輕掃手勢。
使用UISwipeGestureRecognizer處理輕掃手勢的步驟與使用其他手勢處理器的步驟完全相同。UISwipeGestureRecognizer定義瞭如下兩個屬性來設置相關信息:
(1) direction:設置手勢處理器處理該方向的輕掃。
(2) numberOfTouchesRequired:指定該手勢處理器只處理幾個手指的觸碰事件。
使用UIPanGestureRecognizer處理拖動手勢
在用戶使用一個或多個手指在屏幕上拖動的過程中,程序可通過UIPanGestureRecognizer檢測到用戶的這種拖動手勢。
使用UIPanGestureRecognizer處理拖動手勢的步驟能使用其他手勢處理器的步驟完全相同。UIPanGestureRecognizer定義如下兩個屬性來設置該手勢處理器的相關信息:
(1) maximumNumberOfTouches:設置該拖動手勢處理最多支持幾個手指拖動。
(2) minimumNumberOfTouches:設置該拖動手勢處理器最少需要幾個手指一起拖動。
除此之外,該手勢處理器還提供如下方法來獲取拖動相關信息:
(1)-translationInView:獲取該拖動手勢在指定控件上的位移。
(2)-velocityInViwe:獲取該拖動手勢在指定控件上的拖動速度。
使用UILongPressGestureRecognizer處理長按手勢
在用戶使用一個或多個手指在屏幕上長按、不鬆開的過程中,程序可通過UILongPressGestureRecognizer檢測用戶的這種長按手勢。
使用UILongPressGestureRecognizer處理長按手勢的步驟與使用其他手勢處理器的步驟:
(1) minimumPressDuration:指定用戶至少在屏幕上按下多少秒纔會觸發該長按手勢。
默認值爲0.5。
(2) numberOfTouchesRequired:指定必須使用幾個手指在屏幕上長按纔會觸發該手勢。
(3) allowableMovement:指定該長按手勢允許用戶移動手指的最大距離。
創建和使用自定義手勢處理器
開發自定義手勢處理器的步驟如下:
(1) 創建繼承UIGestureRecognizer的子類。
(2) 重寫UIGestureRecognizer基類的觸碰相關的四個方法。
在用戶使用一個或多個手指在屏幕上水平擺動的過程中,程序可通過FKSwingGestureRecognizer檢測用戶的擺動手勢。
在使用FKSwingGestureRecognizer處理擺動手勢的步驟與使用其他手勢處理器的步驟完全相同。FKSwingGestureRecognizer定義瞭如下屬性來設置該手勢處理器的相關信息:
swingCount:設置該拖動手勢處理器要求用戶手指至少擺動幾次。
鍵盤處理
在涉及到表單輸入的界面中,我們通常需要監聽一些鍵盤事件,並根據實際需要來執行相應的操作。在UIWindow.h中定義了6個通知常量配合鍵盤處理:
(1) UIKeyboardWillShowNotification:鍵盤顯示前。
(2) UIKeyboardDidShowNotification:鍵盤顯示之後。
(3) UIKeyboardWillHideNotification:鍵盤隱藏之前。
(4) UIKeyboardDidHideNotification:鍵盤隱藏之後。
(5) UIKeyboardWillChangeFrameNotification:鍵盤大小改變之前。
(6) UIKeyboardDidChangeFrameNotification:鍵盤大小改變之後。
這幾個通知的object對象都是nil,而userInfo字典都包含了一些鍵盤的信息,主要是鍵盤的位置大小信息。
需要注意的是,如果是在兩個大小相同的鍵盤之間切換,則不會發送任何消息。如果是普通鍵盤中類似一中英文鍵盤的切換,只要大小改變了,都會發送一組或多組流程信息。