preferredStatusBarStyle var not working in iOS12?

Solution 1:

This has nothing to do with iOS 12. You just have the rules wrong.

In a navigation controller situation, the color of the status bar is not determined by the view controller’s preferredStatusBarStyle.

It is determined, amazingly, by the navigation bar’s barStyle. To get light status bar text, say (in your view controller):

self.navigationController?.navigationBar.barStyle = .black

Hard to believe, but true. I got this info directly from Apple, years ago.

You can also perform this setting in the storyboard.

Example! Navigation bar's bar style is .default:

enter image description here

Navigation bar's bar style is .black:

enter image description here

NOTE for iOS 13 This still works in iOS 13 as long as you don't use large titles or UIBarAppearance. But basically you are supposed to stop doing this and let the status bar color be automatic with respect to the user's choice of light or dark mode.

Solution 2:

If you choose a same status bar color for each View Controller:

<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>

Ad this to your Info.plist and set status bar color from Project -> Targets -> Status Bar Style by desired color.

On the other hand, in your case, you have a navigation controller which is embedded in a view controller. Therefore, you want to different status bar color for each page.

<key>UIViewControllerBasedStatusBarAppearance</key>
<true/>

Ad this to your Info.plist. Then, create a custom class for your NavigationController. After that you can implement the method:

class LightContentNavigationController: UINavigationController {

    override var preferredStatusBarStyle: UIStatusBarStyle {
        return .lightContent
    }
}

Thats it! Please, inform me whether this was useful!

Solution 3:

If Matt's answer isn't working for you, try adding this line of code before you present your viewController.

viewController = modalPresentationCapturesStatusBarAppearance = true

I encountered a bug where setting modalPresentationStyle to overFullScreen does not give the status bar control to the presented view controller or navigation controller.

Solution 4:

I was using navigation controller for each tab of UITabBarController. Subclassing UINavigationController and overriding childForStatusBarStyle fixed the issue for me.

class MyNavigationController: UINavigationController {
    open override var childForStatusBarStyle: UIViewController? {
        return topViewController?.childForStatusBarStyle ?? topViewController
    }
}