Reputation: 9754
I have below gestures setup:
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self
action:@selector(singleTapDetected:)];
singleTap.numberOfTapsRequired = 1;
[self addGestureRecognizer:singleTap];
UITapGestureRecognizer *doubleClick = [[UITapGestureRecognizer alloc] initWithTarget:self
action:@selector(doubleClickDetected:)];
doubleClick.numberOfTapsRequired = 2;
[self addGestureRecognizer:doubleClick];
[singleTap requireGestureRecognizerToFail:doubleClick];
When I quickly tap 3 times, I find that it will be translated into one double tap event and one single tap event, and introduce a bug for my app.
I want something like if user clicks 3 or more times, only a double tap event will be triggered. Could some one help on this? Thank in advance.
Upvotes: 4
Views: 1901
Reputation: 1556
I am answering this for the benefit of iOS 10 and Swift 3 developers.
Currently in iOS 10 with Swift 3 this problem does not exist. A triple tap if not handled is downgraded to double tap and the corresponding action is fired. Try the example below:
Swift 3 Solution:
doubleTap = UITapGestureRecognizer(target: self, action:#selector(self.doubleTapAction(_:)))
doubleTap.numberOfTapsRequired = 2
singleTap = UITapGestureRecognizer(target: self, action:#selector(self.singleTapAction(_:)))
singleTap.numberOfTapsRequired = 1
singleTap.require(toFail: doubleTap)
self.view.addGestureRecognizer(doubletap)
self.view.addGestureRecognizer(singleTap)
Upvotes: 6
Reputation: 9754
I created a custom recognizer like below also solved my problem:
@implementation MyTapGestureRecognizer
/**
* touchesBegan for custom taps will filter > 2 taps
*
* @param touches touches the recognizer gets
* @param event related event
*/
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesBegan:touches withEvent:event];
if ([touches count] != 1) {
return;
} else {
UITouch *touch = [touches anyObject];
if (touch.tapCount >= 3) {
self.state = UIGestureRecognizerStateFailed;
return;
}
}
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesMoved:touches withEvent:event];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesEnded:touches withEvent:event];
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesCancelled:touches withEvent:event];
}
- (void)reset {
[super reset];
}
@end
Upvotes: 1
Reputation: 34829
You can use the gesture recognizer's delegate to temporarily disable both gestures after a double click. The code below disables the gestures for 0.6 seconds after a double click.
You'll need a couple properties
@property int disableGestures;
@property CFTimeInterval timeStamp;
and some additional initialization
self.disableGestures = NO;
singleTap.delegate = self;
doubleClick.delegate = self;
and you'll need to conform to the <UIGestureRecognizerDelegate>
protocol, and implement the shouldReceiveTouch
method
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
if ( self.disableGestures )
{
if ( CACurrentMediaTime() - self.timeStamp < 0.6 )
return NO;
self.disableGestures = NO;
}
return YES;
}
All that's left is to disable the gestures after a double click
- (void)doubleClickDetected:(UITapGestureRecognizer *)gesture
{
self.disableGestures = YES;
self.timeStamp = CACurrentMediaTime();
// normal processing for the double click goes here
}
Upvotes: 0