iOS 13: NavigationBar BarStyle is ignored when using UINavigationBarAppearance
Asked Answered
A

3

10

I have a custom colour Navigation Bar and I need to make sure the Status Bar colour is set to white. In pre iOS 13 this was easy to do, here is a code snippet from a UIViewController that did the job just fine:

override func viewDidLoad() {
    super.viewDidLoad()

    self.navigationController?.navigationBar.barStyle = .black
}

The issue I'm facing with iOS 13 is that I now need to use the NavigationBar's standardAppearance and scrollEdgeAppearance to undo the forced background transparency in the new UIKit. While I'm able to get the text and background colour of the NavigationBar to what I need with UINavigationBarAppearance() it reverts back my status bar colour to black. Here is a simple example that reproduces the issue:

override func viewDidLoad() {
    super.viewDidLoad()

    self.navigationController?.navigationBar.standardAppearance = UINavigationBarAppearance() // <--- This is the line that reverts my status bar colour back to black
    self.navigationController?.navigationBar.barStyle = .black
}

I'm not sure if this I'm doing something wrong or this is a UIKit bug?

EDIT

Finally managed to fix the issue by adding the bellow two properties to my Info.plist file:

<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>UIStatusBarStyle</key>
<string>UIStatusBarStyleLightContent</string>

Info.plist properties

Agminate answered 19/10, 2019 at 22:39 Comment(1)
Check this thread: #38741148Platysma
A
4

I managed to finally to set the status bar style to white for the whole app. There are many solutions on SO but from my experience some of them can be very iOS specific, i.e. something that worked for someone on iOS 8-12 doesn't necessary mean it will work on iOS 13 with Xcode 11.

Here is my solution that works on iOS 13 with Xcode 11 (also tested on devices running iOS 12 for backwards compatibility) and UINavigationBar.appearance().standardAppearance = UINavigationBarAppearance(). In Info.plist file add the following two properties:

Info.plist properties

<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>UIStatusBarStyle</key>
<string>UIStatusBarStyleLightContent</string>
Agminate answered 20/10, 2019 at 11:7 Comment(1)
This is the correct answer to keep per view controller configuration: https://mcmap.net/q/1071305/-ios-13-navigationbar-barstyle-is-ignored-when-using-uinavigationbarappearanceParanoiac
M
12

The changes for dark mode include a new UIView and UIViewController property named overrideUserInterfaceStyle. This is the preferred way to indicate that you want a specific light/dark style instead of the default behavior where we respond to the current dark mode state.

If you set this on your navigation bar or navigation controller, then you should get the behavior you expect (assuming you want light or dark everywhere). If you need more control, then it may make more sense to subclass UINavigationController to change its behavior (by overriding childViewControllerForStatusBarStyle and returning the top view controller for example).

Mythopoeic answered 24/10, 2019 at 2:49 Comment(4)
Thanks for the answer David. In my specific case I did not need to have multiple status bar colours depending on the view controller, just needed to set one colour for the whole app (hence it would have been an overkill to have to change every single view controller). But I think your answer is useful for those that need this functionality.Agminate
While it seems odd, I was informed the current best practice for allowing the navigation bar to influence the status bar style is to use the UIView.overrideUserInterfaceStyle property.Upandcoming
This is the correct answer. To make the status bar text white, set navBar.overrideUserInterfaceStyle = dark and vice versa for black status bar text.Paranoiac
only downside is it makes menus from buttons in the nav bar in dark mode tooParanoiac
A
4

I managed to finally to set the status bar style to white for the whole app. There are many solutions on SO but from my experience some of them can be very iOS specific, i.e. something that worked for someone on iOS 8-12 doesn't necessary mean it will work on iOS 13 with Xcode 11.

Here is my solution that works on iOS 13 with Xcode 11 (also tested on devices running iOS 12 for backwards compatibility) and UINavigationBar.appearance().standardAppearance = UINavigationBarAppearance(). In Info.plist file add the following two properties:

Info.plist properties

<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>UIStatusBarStyle</key>
<string>UIStatusBarStyleLightContent</string>
Agminate answered 20/10, 2019 at 11:7 Comment(1)
This is the correct answer to keep per view controller configuration: https://mcmap.net/q/1071305/-ios-13-navigationbar-barstyle-is-ignored-when-using-uinavigationbarappearanceParanoiac
G
-1

I learned it the hard way but,

"It isn't enough to just create an instance of UINavigationBarAppearance. "You have to actually set it on a UINavigationBar instance.

This isnt actually phrased by me i found this on a thread on stack over flow i looked for it but couldnt find it for you . However in context what should help you is below .

 //Using this we have to first set up the appearance.

 UINavigationBarAppearance *appearance = [UINavigationBarAppearance new];
 appearance.titleTextAttributes = @{NSFontAttributeName: font};

 //Then u have to use it on the navigation bar and if needed on scroll Edge 

  yourNavigationBar.standardAppearance = appearance;
  yourNavigationBar.scrollEdgeAppearance = appearance; 

 if you want this globally in your navigation bars 

 UINavigationBar.appearance.standardAppearance = appearance;

Another 'hack ' would be to add this in Appdelegate which would work for all the navigation bars in your app .

in Appdelgate

func configureGlobalUI() {

UINavigationBar.appearance().barTintColor = .red
}

Call it in didFinishLaunching

Gailgaile answered 20/10, 2019 at 6:37 Comment(1)
Hi, I'm not sure this answers my questions. I have no issue setting the UINavigationBarAppearance as described in my question, the issue is that it has a side-effect of unsetting the statusBar colour (navigationBar.barStyle = .black). When I'm not using UINavigationBarAppearance then the statusBar colour works correctly.Agminate

© 2022 - 2024 — McMap. All rights reserved.