3

My application is having defaultstatus bar style for pre-login screens. - After login, app uses lightContent style for status bar throughout the app.

All was working fine till iOS 12. It started creating issue with iOS 13 (only when Dark Mode is enabled) .

Here are things which i have already tried, and still not getting things work fine.

  • I did set UIUserInterfaceStyle to Light
  • I did set UIViewControllerBasedStatusBarAppearance to YES
  • Then I tried below code in individual view controller

override var preferredStatusBarStyle: UIStatusBarStyle { return .lightContent }

  • Also added this line in viewDidLoad() of a class file.

setNeedsStatusBarAppearanceUpdate()

But still, I am not getting rid of this status bar related thing. I just simply need my status bar to be dark in screens before login, and once user logged in, it should the light.

Whole application should have identical UI for both dark and light modes. (as it is for OS below iOS 13) Which is working fine right now, but only status bar is changing colour.

Note: Everything is working fine when Dark Mode is disabled. This creating issues only when Dark Mode is enabled.

For my understanding, I created a new project in Xcode and added 3 screens with different status bar appearance.

A Working case
VC1 - Default Style
VC2 - Default Style
VC3 - LightContent Style

A Working case
VC1 - LightContent Style
VC2 - LightContent Style
VC3 - Default Style

Not Working (Failure) case
VC1 - Default Style
VC2 - LightContent Style
VC3 - Default Style

What I assume is - if you use either of style in your application, it works fine regardless of Dark or Light mode of device. But if you combine Default and LightContent both for status bar appearance in your app, then it is not working as expected while dark mode is enabled.

Can any one please help me with this behaviour of Status Bar Style?

Here are my three view controller files. It simply pushes one controller to other one. It is files for the demo project which I have mentioned above. Which has the failure case. view controllers

When Dark Mode is OFF: I always get default status bar style even when I override status bar style in VC2.
When Dark Mode is OFF: I always get lightContent status bar style even when I override status bar style in VC1 & VC3.

Here is my info.plist file Info.plist file of my demo project

Akash Patel
  • 67
  • 1
  • 2
  • 8

4 Answers4

6

In your case, the navigation controller is responsible for maintaining the status bar style. Therefore, you need to subclass your navigation controller and override its preferredStatusBarStyle.

shim
  • 9,289
  • 12
  • 69
  • 108
2

If you don't want to support dark mode in your app (and it seems like you want fixed light and default colour schemes) then you can opt out of it altogether in your Info.plist by setting UIUserInterfaceStyle to either light or dark or on each individual viewcontroller you can override var overrideUserInterfaceStyle: UIUserInterfaceStyle { get { .light } set { //you can leave this empty } }

Edit:

To only change the statusbar appearance without doing anything with darkMode you opt out of dark mode in the Info.plist then add UIUserInterfaceStyle with value YES and in each viewController you want different statusbar style you need to override the preferred statusbar appearance property like so:

 override var preferredStatusBarStyle: UIStatusBarStyle {
        .lightContent
    }
} 

and lastly you call setNeedsStatusBarAppearanceUpdate() in viewDidLoad()

Edit2:

if inside a navigation controller you need to set the above inside a custom navi controller class like this:

import UIKit

class Navi: UINavigationController {

    public var requiredStatusBarStyle: UIStatusBarStyle = .lightContent {
        didSet {
            setNeedsStatusBarAppearanceUpdate()
        }
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }

    override var preferredStatusBarStyle: UIStatusBarStyle {
            requiredStatusBarStyle
    }

}

then in each VC you can set at viewDidAppear the property:

 if let navi = navigationController as? Navi {
            navi.requiredStatusBarStyle = .darkContent
        }

if you don't want a harsh jump between light/dark you can wrap a uiview animation around setneedsstatusbarupdate

public var requiredStatusBarStyle: UIStatusBarStyle = .lightContent {
        didSet {
            UIView.animate(withDuration: 0.5) {
                self.setNeedsStatusBarAppearanceUpdate()
            }
        }
    }
Andras M.
  • 838
  • 7
  • 12
  • Thanks for your response. Your solution is changing my whole view controller in a dark theme. I just need to change the status bar colour, not other UI elements colours. The app needs to be identical for Dark and Light both modes, – Akash Patel Nov 25 '19 at 10:08
  • then as I mentioned opt out of dark mode by changing the Info.plist property to light and then add `UIViewControllerBasedStatusBarAppearance` with value YES. In your viewcontrollers you can override the preferredStatusbarAppearance var like so `override var preferredStatusBarStyle: UIStatusBarStyle { .lightContent }` and don't forget to call `setNeedsStatusBarAppearanceUpdate() ` in viewDidLoad – Andras M. Nov 26 '19 at 07:00
  • Thanks for the effort you're making for this issue. I have updated my question and added screenshots of my ViewController and Info.plist files. I am doing exactly what you're suggesting. But that is not working. – Akash Patel Nov 26 '19 at 15:33
  • Your code doesn't show the relationship between controllers i.e. how are they presented? If you have a storyboard with navigationcontroller then you'll need to create a new class inheriting from UINavigationController and override the above property in that as well as call `setNeedsStatusBarAppearanceUpdate()`. You can add a public function to set the appearance to whatever you need and call it from the pushed VC1/2/3 with the desired dark/light style as a parameter. – Andras M. Nov 27 '19 at 11:47
  • Have you figured this out @AkashPatel? I have same issue, trying to solve it longer than i expected to – Zeljko Marinkovic Jan 25 '23 at 13:01
0

Please try once using this

controller.navigationController?.navigationBar.isTranslucent = false

because in my case it's worked.

  • Thanks for your reply. I tried your solution. But still, I am not getting `default` status bar style when dark mode is ON. It always displays `lightContent` status bar. I have even added `User Interface Style` key in info.plist file with value `Light`. Still no luck! – Akash Patel Nov 25 '19 at 11:11
  • the statusbar is where you have the battery, carrier clock etc, not the navigationbar. – Andras M. Nov 26 '19 at 07:08
-2

You can set default status bar style in General of you project settings.

Gowri G
  • 420
  • 4
  • 18
  • I set default style. But I want to use different styles for different screens throughout the app. So I guess it won't help. – Akash Patel Nov 26 '19 at 04:23