Recently I was trying to figure out why pan gestures weren’t being picked up. The case I was dealing with was a collection view that did not respond to swipe gestures near the edges of the screen.

After consulting with a colleague and looking up some documentation based on his advice, I found the conflict was partially due to the interativePopGestureRecognizer that lives within the UINavigationController. For background, this gesture recogniser was introduced in iOS 7 to allow swiping back to previous view controllers in the navigation controller’s stack.

Disabling it helped solve some of the conflicts.

self.navigationController.interactivePopGestureRecognizer.enabled = NO;

But doing a quick google would have told you that, the reason for this post is another trick I picked up along the way. I wanted to see if there was a way to get a list of gesture recognizers that were conflicting.

The way to do that is to register as a delegate to any of the gesture recognizers that are part of the conflict and implement the following method.

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
    NSLog(@"Gesture Recognizer 1 = %@", gestureRecognizer);
    NSLog(@"Gesture Recognizer 2 = %@", otherGestureRecognizer);
    return YES;

This method will let you know exactly which gesture recognizers are being activated. One challenge with this was that the only gesture recognizer I knew about was the pan gesture recognizer on the collection view, but unfortunately attempting re-assign the pan gesture recognizer on a collection view will result with an assertion failure

Terminating app due to uncaught exception 'NSInvalidArgumentException', 
reason: 'UIScrollView's built-in pan gesture recognizer must have its scroll view as its delegate.'

The way I got this to work without too much hackery was to simply add another gesture recognizer to the edges - UIScreenEdgePanGestureRecognizer was perfect for this.

UIScreenEdgePanGestureRecognizer *gr = [[UIScreenEdgePanGestureRecognizer alloc] initWithTarget:self action:@selector(didSwipe:)];
    gr.delegate = self;
    gr.edges = UIRectEdgeLeft | UIRectEdgeRight;
    [self.view addGestureRecognizer:gr];
2014-12-29 17:08:27.707 TestProject[1678:34518] Gesture Recognizer 1 = UIScreenEdgePanGestureRecognizer: 0x7f9789d7fae0; state = Failed; delaysTouchesBegan = YES; view = UIView 0x7f9789cbb5f0; target= (action=didSwipe:, target=TestViewController 0x7f9789d96c50)
2014-12-29 17:08:27.707 TestProject[1678:34518] Gesture Recognizer 2 = UIPanGestureRecognizer: 0x7f9789c8e610; state = Began; view = UILayoutContainerView 0x7f9789c7c0c0; target= (action=_swipe:, target=UIPopoverController 0x7f9789c8b8d0)

And there you have it, a quick way to check out which gesture recognisers are causing you grief!