Search code examples
iosuinavigationcontrolleruinavigationbarios15uinavigationbarappearance

Navigating to a view controller with a transparent navigation bar from a non-transparent navigation bar on iOS 15


On iOS 15, when navigating to a view controller that has a transparent navigation bar, the animation to the transparent bar isn't working as expected.

However, if you navigate back to the view controller with a transparent navigation bar, the animation works as expected.

This is how I've set up my view controllers:

rootVC

let appearance = UINavigationBarAppearance()
appearance.configureWithDefaultBackground()
appearance.backgroundColor = UIColor.red

self.navigationController?.navigationBar.standardAppearance = appearance
self.navigationController?.navigationBar.scrollEdgeAppearance = self.navigationController?.navigationBar.standardAppearance

firstVC

let appearance = UINavigationBarAppearance()
appearance.configureWithTransparentBackground()

self.navigationController?.navigationBar.standardAppearance = appearance
self.navigationController?.navigationBar.scrollEdgeAppearance = self.navigationController?.navigationBar.standardAppearance

secondVC

let appearance = UINavigationBarAppearance()
appearance.configureWithDefaultBackground()
appearance.backgroundColor = UIColor.yellow

self.navigationController?.navigationBar.standardAppearance = appearance
self.navigationController?.navigationBar.scrollEdgeAppearance = self.navigationController?.navigationBar.standardAppearance

Notice in the following example how smooth the transition is from secondVC -> firstVC but not from rootVC -> firstVC:

video demonstration

Example project: https://github.com/karlingen/NavigationTest

Any ideas why it's behaving like this?


Solution

  • I got the following reply from Apple:

    You should get better behavior using per-item customization, that is setting these properties on their view controller’s UINavigationItem instead of on the UINavigationBar itself. This also frees you from the strict timing necessary for the viewWillAppear: approach to work – as long as your customizations are applied before the view controller is pushed, you should get a good transition. viewDidLoad is generally a good place to do these customizations when using the per-item customization support.

    So we should be using UINavigationItem instead. Using the following code fixed it for me:

    # firstVC.swift    
    override func viewDidLoad() {
        let appearance = UINavigationBarAppearance()
        appearance.configureWithTransparentBackground()
        
        self.navigationItem.standardAppearance = appearance
        self.navigationItem.scrollEdgeAppearance = appearance
    }