Question

I have a case in which 2 completely different behaviors need to take place from a double-tap and a triple-tap on a particular view. I set it up very standard, with the code below:

UITapGestureRecognizer *gestureRecognizerDoubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doubleTapDetected:)];
[gestureRecognizerDoubleTap setNumberOfTapsRequired:2];
[self.theView addGestureRecognizer:gestureRecognizerDoubleTap];

UITapGestureRecognizer *gestureRecognizerTripleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tripleTapDetected:)];
[gestureRecognizerTripleTap setNumberOfTapsRequired:3];
[self.theView addGestureRecognizer:gestureRecognizerTripleTap];

The problem I am having is that if a triple-tap is done, the double-tap method is fired as well, since it detects the 2 taps before the 3rd. So upon a triple-tap, both methods are called.

Obviously this isn't an inherent issue with the code or underlying SDK, since it's fully expected. However, I'm curious if anyone has a clever way to somehow prevent the double-tap functionality to be called if a triple-tap is done? I am assuming I may have to set the double-tap functionality on a delayed timer maybe (which would wait a split second to confirm whether a triple-tap is done), but I'm not sure if there's a better way, or even the best way to set this kind of thing up in a clean fashion?

Thanks in advance for any advice you can offer on this!

Was it helpful?

Solution

You can use requireGestureRecognizerToFail: for this problem:

UITapGestureRecognizer *gestureRecognizerTripleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tripleTapDetected:)];
[gestureRecognizerTripleTap setNumberOfTapsRequired:3];
[self.theView addGestureRecognizer:gestureRecognizerTripleTap];

UITapGestureRecognizer *gestureRecognizerDoubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doubleTapDetected:)];
[gestureRecognizerDoubleTap requireGestureRecognizerToFail:gestureRecognizerTripleTap];
[gestureRecognizerDoubleTap setNumberOfTapsRequired:2];
[self.theView addGestureRecognizer:gestureRecognizerDoubleTap];

The double-tap one won't fire unless the triple-tap one fails.

The class reference, as usual, has some additional information, and mentions this scenario as a great time to use this method.

OTHER TIPS

How about creating 2 recognizers, for 1 and 2 taps respectively (configure them via numberOfTapsRequired). This would obviously take care of detecting 1 and 2 taps. To detect 3 taps, you can check if the 1-tap recognizer has been fired immediately after the 2-tap one.


BTW, while I don't know what your application does, having both a triple and a double tap gestures seems like a potential usability concern. A triple tap by itself is not a commonly known way to interact with an app. I would at least consider a long press instead of a triple tap. That would completely sidestep this technical challenge :)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top