Adding a UIPanGestureRecognizer and a UISwipeGestureRecognizer to same view causes conflicts after setting requireGestureToFail

ios, objective-c, uigesturerecognizer, uipangesturerecognizer

Solution

According to Apple's documentation here (under Declaring a Specific Order for Two Gesture Recognizers) the way to get both `UIPanGestureRecognizer` and `UISwipeGestureRecognizer` to work on the same view is by requiring the `UISwipeGesureRecognizer` to fail before calling the `UIPanGestureRecognizer` (the opposite of what you wrote). This probably has something to do with the fact the a swipe gesture is also a pan gesture but the opposite is not necessarily true (see this SO question).

I wrote this little piece of code and it manages to recognize both pan and swipe gestures:

UIPanGestureRecognizer * pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(panned:)];
UISwipeGestureRecognizer * swipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swiped:)];
[pan requireGestureRecognizerToFail:swipe];
swipe.direction = (UISwipeGestureRecognizerDirectionLeft | UISwipeGestureRecognizerDirectionRight);

-(void)panned:(UIPanGestureRecognizer *)gesture
{
    NSLog(@"Pan");
}

-(void)swiped:(UISwipeGestureRecognizer *)gesture
{
    NSLog(@"Swipe");
}

This doesn't work as well as you'd hope (since you need the swipe gesture to fail there's a small delay before the pan gesture starts) but it does work. The code you posted however gives you the ability to fine tune the gestures to your liking.

Problem

I added a swipe gesture recognizer and a pan gesture recognizer to the same view. These gestures should be exclusive to each other. In order to do this I added the constraint on the swipe gesture ``` [swipeGesture requireGestureToFail:panGesture]; ``` (because the pan gesture should get precedence) Problem is that the pan gesture is always invoked - even during a very fast swipe. In order to over come this I set myself as the pan gesture's delegate. In the delegate method I set up some code as follows: ``` - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer { // check if it is the relevant view if (gestureRecognizer.view == self.myViewWithTwoGestures) { // check that it is the pan gesture if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]) { UIPanGestureRecognizer *pan = (UIPanGestureRecognizer *)gestureRecognizer; CGPoint velocity = [pan velocityInView:gestureRecognizer.view]; // added an arbitrary velocity for failure if (ABS(velocity.y) > 100) { // fail if the swipe was fast enough - this should allow the swipe gesture to be invoked return NO; } } } return YES; } ``` Is there a suggested velocity to ensure good behavior? Is there another way to force the pan gesture to fail?

Original source

Related problems