- UITapGestureRecognizer
- UIPinchGestureRecognizer
- UIRotationGestureRecognizer
- UISwipeGestureRecognizer
- UIPanGestureRecognizer
- UILongPressGestureRecognizer
從命名上不難了解這些類別所對應代表的手勢,分別是 Tap(點一下)、Pinch(二指往內或往外撥動)、Rotation(旋轉)、Swipe(滑動,快速移動)、Pan (拖移,慢速移動)以及 LongPress(長按)。這些手勢別在使用上也很簡單,只要在使用前定義並添加到對應的視圖上即可。
// 定義一個 recognizer, 並加到需要偵測該手勢的 UIView 元件上
- (void)viewDidLoad {
UISwipeGestureRecognizer* recognizer;
// handleSwipeFrom 是偵測到手勢,所要呼叫的方法
recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:selfaction:@selector(handleSwipeFrom)];
// 不同的 Recognizer 有不同的實體變數
// 例如 SwipeGesture 可以指定方向
// 而 TapGesture 則可以指定次數
recognizer.direction = UISwipeGestureRecognizerDirectionUp
[self.view addGestureRecognizer:recognizer];
[recognizer release];
}
- (void)handleSwipeFrom:(UISwipeGestureRecognizer*)recognizer {
// 觸發手勢事件後,在這裏作些事情
// 底下是刪除手勢的方法
[self.view removeGestureRecognizer:recognizer];
}
問題來了。有些手勢其實是互相關聯的,例如 Tap 與 LongPress、Swipe與 Pan,或是 Tap 一次與Tap 兩次。當一個 UIView 同時添加兩個相關聯的手勢時,到底我這一下手指頭按的要算是 Tap 還是 LongPress?如果照預設作法來看,只要「先滿足條件」的就會跳出並呼叫對應方法,舉例來說,如果同時註冊了 Pan 和 Swipe,只要手指頭一移動就會觸發 Pan 然後跳出,因而永遠都不會發生 Swipe;單點與雙點的情形也是一樣,永遠都只會觸發單點,不會有雙點。
那麼這個問題有解嗎?答案是肯定的,UIGestureRecognizer 有個方法叫做requireGestureRecognizerToFail,他可以指定某一個 recognizer,即便自己已經滿足條件了,也不會立刻觸發,會等到該指定的 recognizer 確定失敗之後才觸發。以同時支持單點與雙點的手勢爲例,代碼如下:
- (void)viewDidLoad {
// 單擊的 Recognizer
UITapGestureRecognizer* singleRecognizer;
singleRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:selfaction:@selector(handleSingleTapFrom)];
singleTapRecognizer.numberOfTapsRequired = 1; // 單擊
[self.view addGestureRecognizer:singleRecognizer];
// 雙擊的 Recognizer
UITapGestureRecognizer* double;
doubleRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:selfaction:@selector(handleDoubleTapFrom)];
doubleTapRecognizer.numberOfTapsRequired = 2; // 雙擊
[self.view addGestureRecognizer:doubleRecognizer];
// 關鍵在這一行,如果雙擊確定偵測失敗才會觸發單擊
[singleRecognizer requireGestureRecognizerToFail:doubleRecognizer];
[singleRecognizer release];
[doubleRecognizer release];
}