interactivePopGestureRecognizer corrupts navigation stack on root view controller

后端 未结 5 1456
攒了一身酷
攒了一身酷 2021-02-12 11:19

In my UINavigationController I added custom back buttons with the side effect that it is not possible anymore to swipe left to right to pop the view controller and

相关标签:
5条回答
  • 2021-02-12 11:52
    func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) {
        self.interactivePopGestureRecognizer?.isEnabled = self.viewControllers.count > 1
    }
    

    Updated @rivera solution for Swift 5

    0 讨论(0)
  • 2021-02-12 12:03

    My current solution is to disable the interactivePopGestureRecognizer in the root view controller:

    override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)
    
        self.navigationController?.interactivePopGestureRecognizer?.enabled = false
    }
    

    In the first child view controller I enable it again. But this seems to be more a workaround because I don't understand the actual problem why the navigation stack got messed up in the first place.

    0 讨论(0)
  • 2021-02-12 12:06

    Implement UINavigationControllerDelegate for your navigation controller and enable/disable the gesture recognizer there.

    // Fix bug when pop gesture is enabled for the root controller
    func navigationController(navigationController: UINavigationController, didShowViewController viewController: UIViewController, animated: Bool) {
        self.interactivePopGestureRecognizer?.enabled = self.viewControllers.count > 1
    }
    

    Keeping the code independent from the pushed view controllers.

    0 讨论(0)
  • 2021-02-12 12:06

    Try this code

    func navigationController(navigationController: UINavigationController, didShowViewController vc: UIViewController, animated: Bool) {
        self.interactivePopGestureRecognizer?.enabled = self.vc.count > 1
    }
    
    0 讨论(0)
  • 2021-02-12 12:13

    Here is my solution for this. Swift 4.2

    Implement UIGestureRecognizerDelegate and UINavigationControllerDelegate protocols. In my case I did this in an UITabBarController that would be also my root view controller.

    Then, on viewDidLoad, do:

    override func viewDidLoad() {
        super.viewDidLoad()
    
        self.navigationController?.interactivePopGestureRecognizer?.delegate = self
        self.navigationController?.delegate = self
    }
    

    Then, add the delegate method for UINavigationControllerDelegate and check if it is the root view by counting the number of view on the navigation controller and disable it if it is or enable it if its not.

    func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) {
        let enable = self.navigationController?.viewControllers.count ?? 0 > 1
        self.navigationController?.interactivePopGestureRecognizer?.isEnabled = enable
    }
    

    Lastly, add the UIGestureRecognizerDelegate method

    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldBeRequiredToFailBy otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return true
    }
    

    This should fix the problem without the necessity of manually enabling/disabling the gesture recogniser in every view of your project.

    0 讨论(0)
提交回复
热议问题