'preferredStatusBarStyle var not working in iOS12?

Adding

application.statusBarStyle = .lightContent

to my AppDelegate's didFinishLaunchingWithOptions method nor adding

override var preferredStatusBarStyle: UIStatusBarStyle {
    return UIStatusBarStyle.lightContent
}

to the VC no longer works on iOS12/Xcode10

Any ideas?



Solution 1:[1]

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 2:[2]

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 3:[3]

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
    }
}

Solution 4:[4]

If you have a modal UIViewController the situation becomes very tricky.

Short answer:

  1. Present modal using UIModalPresentationStyle.fullScreen
  2. override preferredStatusBarStyle (in your modal vc)
  3. call setNeedsStatusBarAppearanceUpdate() in viewWillAppear (in your modal vc)

If you don't want to use UIModalPresentationStyle.fullScreen you have to set modalPresentationCapturesStatusBarAppearance

According to apple doc:

When you present a view controller by calling the present(_:animated:completion:) method, status bar appearance control is transferred from the presenting to the presented view controller only if the presented controller's modalPresentationStyle value is UIModalPresentationStyle.fullScreen. By setting this property to true, you specify the presented view controller controls status bar appearance, even though presented non-fullscreen.

The system ignores this property’s value for a view controller presented fullscreen.

Solution 5:[5]

You can set

vc.modalPresentationCapturesStatusBarAppearance = true

to make the customization works.

Solution 6:[6]

Customizing UINavigationController can fix the issue

class ChangeableStatusBarNavigationController: UINavigationController {

    override var preferredStatusBarStyle: UIStatusBarStyle {
        return topViewController?.preferredStatusBarStyle ?? .default
    }
}

Ref: https://serialcoder.dev/text-tutorials/ios-tutorials/change-status-bar-style-in-navigation-controller-based-apps/

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Mazen Kasser
Solution 2 Jeffrey Chang
Solution 3 Adeel Miraj
Solution 4 Levan Karanadze
Solution 5 Santiago
Solution 6 Changwei