Stopping Gesture-Recognizers in Their Tracks

I am currently working on an iOS-based project that uses a UIPageViewController with touchable content inside its views. I ran into a problem when the UIPageViewController's gesture-recognizers were causing the page to turn whenever I touched content near the edges of the page. More specifically, I was attempting to put a UIToolbar inside of a UIPageViewController view. After a couple of hours of trying various techniques including subclassing UIToolbar with an empty touchesBegan:withEvent: and using UIGestureRecognizerDelegate's gestureRecognizer:shouldReceiveTouch: method to cancel the touch, I found two suitable solutions.

The first solution would be to add an empty gesture to the subviews you want to be unaffected by the gesture-recognizer:

UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:nil action:nil];
singleTap.cancelsTouchesInView = NO;
toolbar.gestureRecognizers = [NSArray arrayWithObject:singleTap];

The no-op tap gesture-recognizer stops gesture propagation to the UIPageViewController. The toolbar's UITabBarItems still receive their touches and work.

The second solution to consider, if you have a lot of controls near the edge of the pages, is simply to disable the UIPageController's tap gesture-recognizer altogether:

for (UIGestureRecognizer *recognizer in self.pageViewController.gestureRecognizers) {
    if ([recognizer isKindOfClass:[UITapGestureRecognizer class]]) {
        recognizer.enabled = NO;
    }
}
Posted on Jan 15, 2013
Written by Emlyn Murphy