UIGestureRecognizer in navigationController kills barButtonItem taps

I've run into a problem in an iOS app I build originally with Xcode 8.


In my main list view controller I've added a UITapGestureRecognizer to the navigationController's navigationBar to allow me to toggle the scroll position of the view's tableViewController to the end or the beginning of the list. In Xcode 9 betas where I've tested this (versions 1 and 6 I believe), the UIBarbuttonItems in my navigationController do not get touch events and so their actions are never called. I have tested this scenario by not adding the gesture recognizer to make sure that it wasn't just a problem with barButtonItems, and indeed they work just fine if there is no gesture recognizer in the navigationBar. But I would like to maintain this simple user experience, so removing the gesture recognizer or changing the required number of taps is undesirable.


I filed a Radar for this issue when I first encountered it. It was closed as a duplicate but apparently no action has been taken in the intervening weeks.


The best solution I've come up with is to test the touch location in the UIGestureRecognizerDelegate function gestureRecognizer:shouldReceiveTouch:, but it's a bit fragile, relying on some hard-coded values, and it doesn't provide consistent results.


Can anybody suggest a better workaround?

I had the same issue with a tap gesture added to the main view of a tab managed by UITabBarController. When I tapped on the button, it would always fire the main view tap gesture instead, ignoring the bar button on the navigation bar above the main view. I fixed the issue by unchecking "Cancels touches in view" my tap gesture recognizer in interface builder.

I'm dealing with a similar issue, so I tried what you said and disabled cancelsTouchesInView, but it did not work for me. The reason it didn't work was I created a subclass of UIGestureRecognizer and added that to the navbar. I noticed the navbar doesn't have any gesture recognizers, so the taps on the items are not handled the same as any custom gesture recognizer. What I did was make sure all of the conditions were true for my use case, then set the state to ended. Now, if the conditions were not all true, I removed my custom gesture recognizer, ran a hit test on the point in the navbar, then re-added the gesture recognizer to the navbar.

UIGestureRecognizer in navigationController kills barButtonItem taps
 
 
Q