iosobjective-cuipangesturerecognizer

Resolve conflict between two pan gesture recognizers


I have the following hierarchy:

Each of those views has UIPanGestureRecognizer assigned. Outer pan gesture recognizer is only interested in vertical panning, so I have the delegate method implemented for that:

- (BOOL)gestureRecognizerShouldBegin:(UIPanGestureRecognizer *)panGestureRecognizer {
    CGPoint velocity = [panGestureRecognizer velocityInView:panGestureRecognizer.view];
    return fabs(velocity.y) > fabs(velocity.x);
}

However Subview's pan gesture always takes precedence in recognition. Is there any way to make outer pan gesture recognizer to recognize first and then if it fails, pan gesture from subview can take over?

I tried simultaneous recognition and it works, but then both recognizers start panning:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer 

    shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
        return YES;
    }

Solution

  • Since iOS 7, UIGestureRecognizerDelegate Protocol has already declared two delegate methods for your need, you can either use |gestureRecognizer:shouldRequireFailureOfGestureRecognizer:| or |gestureRecognizerShouldBegin:shouldBeRequiredToFailByGestureRecognizer:| but in the opposite way.

    The following snippet is my UIPanGestureRecognizer delegate implementation:

    - (BOOL)gestureRecognizerShouldBegin:(UIPanGestureRecognizer *)panGestureRecognizer {
        CGPoint velocity = [panGestureRecognizer velocityInView:panGestureRecognizer.view];
        return fabs(velocity.y) > fabs(velocity.x);
    }
    
    - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
        if (otherGestureRecognizer == panGestureOfSubView) {
            return YES;
        }
    
        return NO;
    }