No Swipe Back when hiding Navigation Bar in UINavigationController

前端 未结 18 682
生来不讨喜
生来不讨喜 2020-12-04 06:34

I love the swipe pack thats inherited from embedding your views in a UINavigationController. Unfortunately i cannot seem to find a way to hide the Naviga

18条回答
  •  独厮守ぢ
    2020-12-04 07:11

    Problems with Other Methods

    Setting the interactivePopGestureRecognizer.delegate = nil has unintended side-effects.

    Setting navigationController?.navigationBar.hidden = true does work, but does not allow your change in navigation bar to be hidden.

    Lastly, it's generally better practice to create a model object that is the UIGestureRecognizerDelegate for your navigation controller. Setting it to a controller in the UINavigationController stack is what is causing the EXC_BAD_ACCESS errors.

    Full Solution

    First, add this class to your project:

    class InteractivePopRecognizer: NSObject, UIGestureRecognizerDelegate {
    
        var navigationController: UINavigationController
    
        init(controller: UINavigationController) {
            self.navigationController = controller
        }
    
        func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
            return navigationController.viewControllers.count > 1
        }
    
        // This is necessary because without it, subviews of your top controller can
        // cancel out your gesture recognizer on the edge.
        func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
            return true
        }
    }
    

    Then, set your navigation controller's interactivePopGestureRecognizer.delegate to an instance of your new InteractivePopRecognizer class.

    var popRecognizer: InteractivePopRecognizer?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setInteractiveRecognizer()
    }
    
    private func setInteractiveRecognizer() {
        guard let controller = navigationController else { return }
        popRecognizer = InteractivePopRecognizer(controller: controller)
        controller.interactivePopGestureRecognizer?.delegate = popRecognizer
    }
    

    Enjoy a hidden navigation bar with no side effects, that works even if your top controller has table, collection, or scroll view subviews.

提交回复
热议问题