UIStatusBarStyle PreferredStatusBarStyle does not work on iOS 7

I discovered that if your ViewController is inside a navigationController then the navigationController’s navigationBar.barStyle determines the statusBarStyle.

Setting your navigationBar’s barStyle to UIBarStyleBlackTranslucent will give white status bar text (ie. UIStatusBarStyleLightContent), and UIBarStyleDefault will give black status bar text (ie. UIStatusBarStyleDefault).

Note that this applies even if you totally change the navigationBar’s color via its barTintColor.


OK, here's the trick. You do have to add the key "View controller-based status bar" and set the value to No.

This is counter to what it appears the meaning of this key is, but even if you set the value to No, you can still change the appearance of the status bar, and whether it shows or not in any view controller. So it acts like "Yes" but set it to "No"!

Now I can get the status bar white or dark.


For preferredStatusBarStyle() to work within UINavigationController and UITabBarController I add the following code, which will get the preferred status bar style from the currently visible view controller.

extension UITabBarController {
    public override func childViewControllerForStatusBarStyle() -> UIViewController? {
        return selectedViewController
    }
}

extension UINavigationController {
    public override func childViewControllerForStatusBarStyle() -> UIViewController? {
        return visibleViewController
    }
}

For Swift 3 those are not methods but properties:

extension UITabBarController {
    open override var childViewControllerForStatusBarStyle: UIViewController? {
        return selectedViewController
    }
}

extension UINavigationController {
    open override var childViewControllerForStatusBarStyle: UIViewController? {
        return visibleViewController
    }
}

The Swift 4.2 properties have been renamed:

extension UITabBarController {
   open override var childForStatusBarStyle: UIViewController? {
        return selectedViewController
    }
}

extension UINavigationController {
   open override var childForStatusBarStyle: UIViewController? {
        return visibleViewController
    }
}

Usage

class ViewController: UIViewController {

    // This will be called every time the ViewController appears
    // Works great for pushing & popping
    override var preferredStatusBarStyle: UIStatusBarStyle {
        return .lightContent
    }

}

I may be coming to this a bit late, but incase anyone else is looking for a working and verified app wide solution.

@mxcl is correct in describing why this is happening. In order to correct it, we simply create an extension (or category in obj-c) that overrides the preferredSatusBarStyle() method of UINavigationController. Here is an example in Swift:

extension UINavigationController {
    public override func preferredStatusBarStyle() -> UIStatusBarStyle {
        if let rootViewController = self.viewControllers.first {
            return rootViewController.preferredStatusBarStyle()
        }
        return super.preferredStatusBarStyle()
    }
}

This code simply extracts the first view controller (the root view controller) and unwraps it (in obj-c just check that it is not nil). If the unwrap is successful (not nil) then we grab the rootViewControllers preferredStatusBarStyle. Otherwise we just return the default.

Hope this helps anyone who might need it.


To provide more detail into the accepted answer, put the following line in your app delegate's didFinishLaunchingWithOptions: method:

[UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent;

Then, in your Info.plist, add View controller-based status bar appearance and set it to NO.

I believe that's how it should be done, NOT from the navigation controller, if you want the same status bar color for the entire app. You might have screens that are not necessarily embedded in a UINavigationController, or a different UINavigationController subclass somewhere else, and other things.

EDIT: You can also do it without typing any code: https://stackoverflow.com/a/18732865/855680