2.2手勢識別的狀態和手勢識別器幕后原理
(一)手勢的狀態
// 手勢狀態
typedef NS_ENUM(NSInteger, UIGestureRecognizerState) {
UIGestureRecognizerStatePossible, // 尚未識別是何種手勢操作(但可能已經觸發了觸摸事件),默認狀態
UIGestureRecognizerStateBegan, // 手勢已經開始,此時已經被識別,但是這個過程中可能發生變化,手勢操作尚未完成
UIGestureRecognizerStateChanged, // 手勢狀態發生轉變
UIGestureRecognizerStateEnded, // 手勢識別操作完成(此時已經松開手指)
UIGestureRecognizerStateCancelled, // 手勢被取消,恢復到Possible狀態
UIGestureRecognizerStateFailed, // 手勢識別失敗,恢復到Possible狀態
UIGestureRecognizerStateRecognized = UIGestureRecognizerStateEnded // 手勢識別完成,同UIGestureRecognizerStateEnded
};
(二)離散型手勢識別器和連續型手勢識別器之間的對比:
調用回調方法區別:
14636547400991.png
狀態之間切換區別:
14636543727544.png
總結:離散型手勢一旦識別就無法取消,而且只會調用一次手勢操作事件(初始化手勢時指定的回調方法)。而連續型手勢會多次調用手勢操作事件,而且在連續手勢識別后可以取消手勢.兩者調用回調方法的次數是不同的.
(三)手勢識別器幕后原理
手勢識別器是在正常的響應者鏈條
之上.默認情況下,UIWindow首先將觸摸事件發送給手勢識別器,只有手勢識別器無法處理觸摸事件時,事件才會被轉發給響應者鏈條
.
應用程序判斷手勢是否別識別的過程:
手勢識別器進入UIGestureRecognizerStatePossible
狀態:
離散型手勢:
1>手勢識別器將判斷手勢處于`UIGestureRecognizerStateRecognized`
還是`UIGestureRecognizerStateFailed`狀態.
2>如果是`UIGestureRecognizerStateRecognized`狀態,手勢識別器將處理事件,
并調用指定的回調方法.
如果是`UIGestureRecognizerStateFailed`狀態,手識別器將把觸摸事件裝發
給`響應者鏈條`.
連續型手勢:
1>手勢識別器將判斷手勢處于`UIGestureRecognizerStateBegan`
還是`UIGestureRecognizerStateFailed`狀態.
2>如果手勢處于UIGestureRecognizerStateBegan狀態,手勢識別器將處理事件,并
調用回調方法.然后當手勢發生變化時,都將進入`UIGestureRecognizerStateChanged`
狀態,并調用指定的回調方法.這個過程不斷重復,直到觸摸結束并進入`UIGestureRecognizerStateEnded`
狀態.如果觸摸方式不再符合預期手勢,將進入`UIGestureRecognizerStateCancelled`
狀態.
如果手勢處于`UIGestureRecognizerStateFailed`狀態,手勢識別器將把觸摸事件裝發
給`響應者鏈條`.
經驗談:
手勢從狀態
UIGestureRecognizerStatePossible
變化到狀態UIGestureRecognizerStateFailed
所需的事件可能很長.如果手勢識別器處理觸摸事件的速度慢的莫名其妙,最好在手勢處理方法中輸出相關的狀態,這樣就可以清楚地知道手勢狀態的變換情況,就可以確定延遲出現在什么地方.