UINavigationController Interactive Pop Gesture Not Working?
Solution 1
Eh, looks like I just had to set the gesture delegate and implement the following:
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}
Solution 2
I have found that when using custom back buttons, the interactive pop gesture stops working (my take is that Apple cannot foresee how your custom back button will behave, so they disable the gesture).
To fix this, as other mentioned before, you can set the interactivePopGestureRecognizer.delegate
property to nil
.
In Swift, this can easily be done across your entire application by adding an extension for :UINavigationController
like this
extension UINavigationController {
override public func viewDidLoad() {
super.viewDidLoad()
interactivePopGestureRecognizer?.delegate = nil
}
}
Updated answer
Seems like setting the delegate to nil
causes the app UI to freeze in some scenarios (eg. when the user swipes left or right on the top view controller of the navigation stack).
Because gestureRecognizerShouldBegin
delegate method cannot be handled in an extension, subclassing UINavigationController
seems like the best solution:
class NavigationController: UINavigationController, UIGestureRecognizerDelegate {
/// Custom back buttons disable the interactive pop animation
/// To enable it back we set the recognizer to `self`
override func viewDidLoad() {
super.viewDidLoad()
interactivePopGestureRecognizer?.delegate = self
}
func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
return viewControllers.count > 1
}
}
Solution 3
Look at this response and comments. All you have to do is set your navigation controller's interactive pop gesture recognizer's delegate to nil
:
self.navigationController.interactivePopGestureRecognizer.delegate = nil;
Setting it to a casted self to id<UIGestureRecognizerDelegate>
also works because all methods in the protocol are optional, but I think setting the delegate to nil
is more appropriate in this case.
Solution 4
You can put this line in the viewDidLoad method.
self.navigationController.interactivePopGestureRecognizer.delegate = (id<UIGestureRecognizerDelegate>)self;
Solution 5
My answer is based on Eneko's answer but uses only an extension on UINavigationController and works in Swift 5:
extension UINavigationController: UIGestureRecognizerDelegate {
override open func viewDidLoad() {
super.viewDidLoad()
interactivePopGestureRecognizer?.delegate = self
}
public func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
return viewControllers.count > 1
}
}
Comments
-
Aaron Wojnowski over 2 years
So I have a navigation controller in my built for iOS 7 app. The titleView is visible, as well as the back button and navigation bar its self. For some reason, the interactive pop gesture (swipe from the left edge) isn't working. Nothing happens. When I log the gesture, it is not nil. Is there anything special I have to do to enable this functionality? What could cause it not to work?
-
jonbauer over 8 yearsi only had success with this when in viewDidAppear
-
User about 8 yearsThis "works" but shortly after causes very strange issues to the point of freezing the app (tested with iOS 8, device)
-
codelover almost 8 yearsIve checked this but very creepy problem, when I have this fixed then if the user slides half way and then come back i see the next controller overlapped on the previous view controller. I see the Previous view controller and the next overlapped is transparent like transparent glass. So user happens to be locked this state. Any idea. This is something View did appear / will appear handling issue.
-
joern over 7 yearsThis seems to work, but it turns out that under certain circumstances it freezes the app. I think it happens when the interactive pop gesture is triggered while a view controller is being pushed. A safer way would be to subclass
UINavigationController
. In the subclass set theinteractivePopGestureRecognizer.delegate
to self and prevent the interactive pop gesture from being recognized while a new view controller is pushed. -
Eneko Alonso over 7 yearsIndeed, I have found that issue too, seems to affect only the top view controller of the navigation controller stack. I have updated my answer with a different solution based in subclassing.
-
Alex almost 7 years@Eneko Alonso perfect! Just as you said, if user swipes left or right and then taps a button - push view controller is glitched. Subclassing fixes the problem 100%
-
user7097242 about 6 years@EnekoAlonso Im having a similar issue when I set the navigation bar hidden. I loose the swipe back functionality. Is there anyway you can help out with this? I posted this question for clarity: stackoverflow.com/questions/48954413/…
-
Hindu over 4 yearsit is not working to me with IOS 13. Are you have any suggestion?
-
MMK over 4 yearsWorked with ios 13.1
-
SoftDesigner almost 4 yearsThis is so stupid, but it works! Why have Apple changed that?... Thx a bunch!
-
DeyaEldeen over 3 yearsThanks a lot SoftDesigner ✅.