iOS: Specify status bar text color when using UINavigationBarAppearance now barstyle is ignored

ios, swift, uikit, uinavigationbar, uistatusbar

Solution

I was able to set the status bar text white using:

navController.navigationBar.overrideUserInterfaceStyle = .dark

Note that bencallis, the creator of this question, warns that this solution "results in menus from buttons in the nav bar in dark mode too which is not what I want". I don't use menus like this so that is not a problem for me. Maybe it's not for you too.

Problem

Problem I have an app that has different colour navigation bars for different flows. Some navigation bars have a light background and require black status bar text. Others have a darker navigation bar and require white status bar text. As part of the move to iOS15 I have updated an app I am working on to use the `UINavigationBarAppearance` approach to navigation bar styling. I am able to style everything as I could before other than the status bar color. Previously I have been using the `barStyle` property on navigation bar to set the status bar text color. ``` navigationBar.barStyle = .black ``` This does not appear to work when using `UINavigationBarAppearance`. Sample code Old styling approach ``` override func viewDidLoad() { super.viewDidLoad() let navigationBar = navigationController?.navigationBar // Style using old approach navigationBar?.barTintColor = UIColor.purple navigationBar?.titleTextAttributes = [.foregroundColor: UIColor.white] // Use barStyle to set status bar text color to white // This only work when using the old styling approach navigationBar?.barStyle = .black } ``` New styling approach ``` override func viewDidLoad() { super.viewDidLoad() let navigationBar = navigationController?.navigationBar // Style nav bar using new Appearance API let navBarAppearance = UINavigationBarAppearance() navBarAppearance.backgroundColor = UIColor.purple navBarAppearance.titleTextAttributes = [.foregroundColor: UIColor.white] navigationBar?.standardAppearance = navBarAppearance navigationBar?.scrollEdgeAppearance = navBarAppearance // Use barStyle to set status bar text color to white // This only work when using the old styling approach navigationBar?.barStyle = .black } ``` Alternatives Force dark/light mode on the navigation bar It is possible to make the status bar text white using the property `overrideUserInterfaceStyle`. To make the status bar text white, set ``` navigationBar.overrideUserInterfaceStyle = dark ``` However, this results in menus from buttons in the nav bar in dark mode too which is not what I want. Subclass UINavigationController I imagine I could also subclass UINavigationController and explicitly override the `preferredStatusBarStyle` to force black or white text. Having to use a subclass everywhere we make new navigation controllers just to specify the status bar text color seems a bit extreme. Anything else? I'm not sure if there is a better approach to this?

Original source