iOS 13: NavigationBar BarStyle is ignored when usi

2020-07-13 10:01发布

问题:

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>

回答1:

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).



回答2:

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:

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


回答3:

Is there a solution to this without setting UIViewControllerBasedStatusBarAppearance to false? I want to change the status bar colour per view controller.



回答4:

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