halfblood17
halfblood17

Reputation: 657

Navigation bar back button disappears when hiding and showing navigation bar

I'm trying to recreate a behaviour similar to the one seen for the UINavigationController in Apple News app.
I have two controllers A and B, A is embedded in a UINavigationController and has a segue to B.
The navigation bar in A is hidden while in B its visible and when moving from one to the other it animates correctly.

To achieve this I'm setting A as the delegate for UINavigationController and adding

func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationController.Operation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
    if operation == .push {
        navigationController.setNavigationBarHidden(false, animated: false)
    }
    return nil
}

func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
    if let coordinator = navigationController.topViewController?.transitionCoordinator {
        if let _ = viewController as? ViewControllerA {
           navigationController.setNavigationBarHidden(true, animated: false)
        }

        coordinator.notifyWhenInteractionChanges { (context) in
            if context.isCancelled == true {
                navigationController.setNavigationBarHidden(false, animated: false)
            }
        }
    }
}

The issue I'm encountering is with the swipe back gesture.
When the gesture starts I'm hiding the navigation bar in order for it to not be visible on ViewControllerA but if the gesture is cancelled I'm showing the bar again.
Unfortunately when showing it again, while the bar itself is visibile, the back button doesn't reappear for some reason.
Do you know why is that?

An example of the issue

Upvotes: 2

Views: 1727

Answers (1)

André Slotta
André Slotta

Reputation: 14030

I think you do not have to work with the navigation controller delegate in this case but simply show / hide the navigation bar in the view controllers' viewWillAppear methods:

class ViewControllerA: UIViewController {

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        navigationController?.setNavigationBarHidden(true, animated: animated)
    }

}

class ViewControllerB: UIViewController {

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        navigationController?.setNavigationBarHidden(false, animated: animated)
    }

}

I think this is the simpler solution that does not make any problems with missing back bar button items. :)

Upvotes: 4

Related Questions