I have found four different way to change the iOS status bar in Xcode. Why are there so many and what are the differences?

i0S Swift Issue

Question or problem in the Swift programming language:

I’ve been trying to change the color of the status bar in my Swift app, and I’ve identified four ways to do this in XCode. Yet, I have only been able to successfully use method 3:

1. Simulated Metrics (For Storyboard display only)

2. Change in General->Deployment Info->Status Bar Style

Make sure the following Info.list setting is set to “NO”:

View controller-based status bar appearance : NO

Select either “Light” or “Default” in the dropdown box here:

General->Deployment Info->Status Bar Style

3. Set it Manually

Make sure the following Info.plist setting is set to “NO”:

View controller-based status bar appearance : NO

Insert the following code (usually in didFinishLaunchingWithOptions):

UIApplication.sharedApplication().statusBarStyle = .LightContent

4. Override “preferredStatusBarStyle()”

Make sure the following Info.plist property exists and is set to “YES”:

View controller-based status bar appearance : YES

Then add the following code to the UIViewController (or derived class) which is set for your ViewController in Storyboard:

override func preferredStatusBarStyle() -> UIStatusBarStyle {
    return UIStatusBarStyle.LightContent
}

My current understanding

Simulated Metrics is just for display and provides no actual change during runtime. I believe setting manually and changing the setting in the general tab probably do the same thing under the hood, but I’m not sure. I imagine there is also a way to set this property directly for individual view controllers.

Question

For some reason, the only method which has actually worked for me is method 3, setting manually. None of the other methods provide any change. Personally, I would prefer to override in a derived class so I have a central place for my shared UIViewController styles.

How to solve the problem:

Option 1

This does nothing because it’s just a simulated metric. You can set it in interface builder, but simulated metrics are just simulated and not applied at run time.

Option 2

This option prevents individual view controllers from setting the status bar appearance (due to the Info.plist setting), and it relies on a default color set in deployment settings, but that value can be changed at run time (see option 3).

Option 3

Like option 2, this option prevents individual view controllers from setting the status bar appearance (due to the Info.plist setting), but unlike option 2, we’re dynamically setting the color at run time. We can do this just in the app delegate at launch… or we can change it at various other times. Maybe we have a night mode like the Google Maps app, or maybe we’re letting the user configure their own theme colors somewhere.

Option 4

If you are embedding in a UINavigationController, then you will need to subclass UINavigationController and override “preferredStatusBarStyle()” here.

You may be missing a step, outlined here. In viewDidLoad, try specifying that you want the opportunity to set the status bar.

override func viewDidLoad() {
    super.viewDidLoad()

    setNeedsStatusBarAppearanceUpdate()
}

As to why there are different approaches for seemingly the same thing, we must first realize that these aren’t actually the same thing.

Again, let’s break it down.

  • Option 1 isn’t a run time change, so it’s really not interesting to us.
  • Option 2 & 3 are almost the same thing.
  • Option 4 is different from option 2 & 3.

Why do we have your option 2/3 and your option 4?

Because in some applications, you might want the same status bar color for every view controller in your app, but that status bar color might be different based on some setting.

Consider, for example, Google Maps app. At night, the app turns black and the status bar needs to show up white, but at day, the app is white and the status bar needs to be black. It’s the same for every view controller, so the code to set the color needs to just be implemented in one place (without requiring every view control inherit from the same base parent). For this, we likely want your option 2/3.

But consider an app that has different colored view controllers where the some of them look better with a white status bar and others look better with a black. For this approach, we want your option 4 and let each view controller individually specify what color the status bar should be.

In short, your option 2/3 is a global status bar setting that applies no matter where you are in the app, while option 4 is a local, per-VC setting.

Hope this helps!