它可以設定成,發生特定點按次數時,執行指定的方法。
但這邊有個問題,假設我們想在一個 View 上實作 user 點按 1 次跟連點 2 次時會發生不同動作,
程式碼大概是這樣:
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap1)];
singleTap.numberOfTapsRequired = 1;
[self.view addGestureRecognizer:singleTap];
UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap2)];
doubleTap.numberOfTapsRequired = 2;
[self.view addGestureRecognizer:doubleTap];
問題在於兩個辨識器並不知道彼此的存在,所以當 user 執行連按 2 次這個動作時,不只 tap2 這個 method 會被呼叫,連 tap1 也會被呼叫,而且是兩次,
解決方法是建立個失敗的(failure)的需求,告訴 tap1 只有在 tap2 無法辨識及回應 user 的輸入時,
才會去觸發其動作。
[singleTap requireGestureRecognizerToFail:doubleTap];
實作:
#import "ViewController.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UILabel *singleLabel;
@property (weak, nonatomic) IBOutlet UILabel *doubleLabel;
@property (weak, nonatomic) IBOutlet UILabel *tripleLabel;
@property (weak, nonatomic) IBOutlet UILabel *quadrupleLabel;
- (void)tap1;
- (void)tap2;
- (void)tap3;
- (void)tap4;
- (void)eraseMe:(UILabel *)label;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap1)];
singleTap.numberOfTapsRequired = 1;
singleTap.numberOfTouchesRequired = 1;
[self.view addGestureRecognizer:singleTap];
UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap2)];
doubleTap.numberOfTapsRequired = 2;
doubleTap.numberOfTouchesRequired = 1;
[self.view addGestureRecognizer:doubleTap];
[singleTap requireGestureRecognizerToFail:doubleTap];
UITapGestureRecognizer *tripleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap3)];
tripleTap.numberOfTapsRequired = 3;
tripleTap.numberOfTouchesRequired = 1;
[self.view addGestureRecognizer:tripleTap];
[doubleTap requireGestureRecognizerToFail:tripleTap];
UITapGestureRecognizer *quadrupleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap4)];
quadrupleTap.numberOfTapsRequired = 4;
quadrupleTap.numberOfTouchesRequired = 1;
[self.view addGestureRecognizer:quadrupleTap];
[tripleTap requireGestureRecognizerToFail:quadrupleTap];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
_singleLabel = nil;
_doubleLabel = nil;
_tripleLabel = nil;
_quadrupleLabel = nil;
}
#pragma mark - Added methods
- (void)tap1 {
_singleLabel.text = @"Single Tap Detected";
[self performSelector:@selector(eraseMe:) withObject:_singleLabel afterDelay:1.6f];
}
- (void)tap2 {
_doubleLabel.text = @"Double Tap Detected";
[self performSelector:@selector(eraseMe:) withObject:_doubleLabel afterDelay:1.6f];
}
- (void)tap3 {
_tripleLabel.text = @"Triple Tap Detected";
[self performSelector:@selector(eraseMe:) withObject:_tripleLabel afterDelay:1.6f];
}
- (void)tap4 {
_quadrupleLabel.text = @"Quadruple Tap Detected";
[self performSelector:@selector(eraseMe:) withObject:_quadrupleLabel afterDelay:1.6f];
}
- (void)eraseMe:(UILabel *)label {
label.text = @"";
}
@end
以上我們可看出,當 user 點按 1 下螢幕時,singleTap 需要等到 doubleTap 的失敗才能觸發自己的事件,
如果 user 在系統設定的點按間隔時間內按下第二次,
則此手勢便會視為點按 2 次,並跳過 singleTap 而去執行 doubleTap 所指定的動作。
反之,若 user 沒在點按間隔時間內按下第二次,
則 doubleTap 會告訴 singleTap 它失敗了,singleTap 才會開始執行其動作。
以此類推,doubleTap 需要 tripleTap 的失敗、tripleTap 需要 quadrupleTap 的失敗。