How to disable automatic transparent navbar in iOS 15
Xcode 13 along with iOS 15 SDK brings substantial changes to UINavigationBar.
Published: Oct. 6, 2021 Sponsored App StoreApple updated how navigation bars look in iOS 15 (once your app is build with Xcode 13) and now they are by default transparent if there isn't any content behind them.
So in practice this means that the old "bar" with different background is now gone and comes back only after you scrolled the content.
Because this is enabled by default, it might cause visual issues for your app. I had to fix this in couple apps and here is how do to it.
You need to use the UINavigationBarAppearance
which is available since iOS 13.
Restoring pre-iOS15 look
Apologies for the syntax coloring.. looks like the #available
is causing issues
The basic fix looks like this:
if #available(iOS 15.0, *) {
let navigationBarAppearance = UINavigationBarAppearance()
navigationBarAppearance.configureWithDefaultBackground()
UINavigationBar.appearance().standardAppearance = navigationBarAppearance
UINavigationBar.appearance().compactAppearance = navigationBarAppearance
UINavigationBar.appearance().scrollEdgeAppearance = navigationBarAppearance
}
The configureWithDefaultBackground
makes the navigation bar appear as translucent.
The main key here is that we are setting the new scrollEdgeAppearance
to be the same as standard one. This turns off the automatic transparency for all navigation bars in your app, since with the UINavigationBar.appearance()
we are using the appearance proxy.
The code above should ideally go to AppDelegate
when the app starts.
Toggling transparency with this API
Another issue I had to solve was that the app I needed to fix toggled navigation bar to be transparent on some screens and the old way of doing this no longer worked with Xcode 13.
The switching now looks like this:
if #available(iOS 15.0, *) {
if isTransparent {
let navigationBarAppearance = UINavigationBarAppearance()
navigationBarAppearance.configureWithTransparentBackground()
navigationController.navigationBar.tintColor = .white
navigationItem.scrollEdgeAppearance = navigationBarAppearance
navigationItem.standardAppearance = navigationBarAppearance
navigationItem.compactAppearance = navigationBarAppearance
} else {
let navigationBarAppearance = UINavigationBarAppearance()
navigationBarAppearance.configureWithDefaultBackground()
navigationController.navigationBar.tintColor = .label
navigationItem.scrollEdgeAppearance = navigationBarAppearance
navigationItem.standardAppearance = navigationBarAppearance
navigationItem.compactAppearance = navigationBarAppearance
}
navigationController.setNeedsStatusBarAppearanceUpdate()
}
Of course the colors used here are for illustration. Feel free to use any other.
Don't forget you can use the preferredStatusBarStyle
property to control which style should the system status bar use.