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?