43

Just downloaded the new xCode 10.0 and saw that the old statusBarStyle has been deprecated since iOS 9.0.

Warning: Setter for 'statusBarStyle' was deprecated in iOS 9.0: Use -[UIViewController preferredStatusBarStyle]

Deprecated code: UIApplication.shared.statusBarStyle = .default

I tried using self.preferredStatusBarStyle, but found out the property is only a getter. So anyone knows how to set the statusBarStyle?


Edit

I want to change the statusBarStyle inside a function, where a user can switch between different themes. For example:

func changeStatusBar(toDarkMode: Bool) {
    if toDarkMode {
        // Set to light statusBarStyle
    } else { 
        // Set to default
    }
}
Community
  • 1
  • 1
Jacob Ahlberg
  • 2,352
  • 6
  • 22
  • 44

6 Answers6

45

Add View controller-based status bar appearance NO in Info.plist

And select Light in Status Bar Style in Deployment Info

enter image description here

Pavlos
  • 906
  • 1
  • 11
  • 29
35

Set your darkMode variable using the same code you have now, then use it in the computed variable that the system is expecting:

var darkMode = false
override var preferredStatusBarStyle : UIStatusBarStyle {
    return darkMode ? .default : .lightContent
}

Depending on the context you may need to force a refresh of the screen for it to take effect. You would do that with the following call:

setNeedsStatusBarAppearanceUpdate()
Paul King
  • 1,881
  • 20
  • 23
  • 1
    It seems good, but the statusBarStyle doesn't get updated even if I use this line of code. I used a didSet closure in the darkMode boolean, that updates the statusBarAppearance. It gets called whenever I change the bool value. But the statusBarStyle doesn't change. Do you have any clue on what it could be? – Jacob Ahlberg Jun 07 '18 at 06:58
  • Are you setting this in the root viewController? See this discussion in Apple's docs: https://developer.apple.com/documentation/uikit/uiviewcontroller/1621433-childforstatusbarstyle – Paul King Jun 07 '18 at 18:05
  • @paulking I am using same But In iPHOne XS, XR and XS max default launch(splash) screen Not Showing light content of status bar. – BalKrishan Yadav Sep 28 '18 at 14:05
  • @BalKrishanYadav, launch/splash screens do not execute any code, so in this case you would need to set the "Status Bar Style" for the app target under General/Deployment Info. – Paul King Oct 01 '18 at 17:53
  • as @paulking suggested setting it in the rootviewcontroller does the trick. – James Rochabrun Jan 05 '19 at 02:35
  • If you use a Navigation Controller, which a lot of apps do, use the extension mentioned in the answer by CryingHippo or else this won't work. – Ben May 16 '19 at 17:33
27

In swift4, You can use this block of code below viewDidLoad() in your ViewController-

override var preferredStatusBarStyle : UIStatusBarStyle {
    return .lightContent
}
Rashed
  • 2,349
  • 11
  • 26
  • 1
    I'm actually switching between two different themes (light and dark) so I have to change the statusBarStyle inside a function. You have any clue on how? – Jacob Ahlberg Jun 05 '18 at 06:52
  • set a tag for ur themes inside your function for those two different theme. E.g. for theme1 set tag1 then if it gets tag 1 then it will show status bar light. Same for others. – Rashed Jun 05 '18 at 06:57
  • I'm actually using a mapView which goes behind the statusBar and whenever a user changes the mapType from default to satellite I have to change the statusBar so it doesn't blend into the mapView. So I can't really set a tag on that... Any other suggestions? – Jacob Ahlberg Jun 05 '18 at 10:10
  • @Md Rashed Pervez I added your code from above, but it doesn't seem to make a difference. – icekomo Sep 13 '18 at 02:26
  • @icekomo did you put the code below the viewDidLoad() in your ViewController – Rashed Sep 13 '18 at 06:04
  • @MD Rashed Pervez I did. I also read that having a Nav Controller might make a difference. Do you know anything about that? – icekomo Sep 13 '18 at 11:35
  • @icekomo Please go through this tutorial - https://www.youtube.com/watch?v=jz_pT0MELxE – Rashed Sep 13 '18 at 11:51
  • @MD Rashed Pervez, thanks for the video. I followed the steps but autocomplete doesn't give me the option for that function he is using. Did something change from the time the video was posted until now? – icekomo Sep 13 '18 at 21:22
  • From what I have read, this chagned, and it is no longer a func. https://stackoverflow.com/questions/38862208/preferredstatusbarstyle-removed-in-swift-3 – icekomo Sep 13 '18 at 21:23
  • Can you explain why it should be placed below viewDidLoad() please? @md-rashed-pervez – rommex Mar 26 '20 at 11:30
13

If you use UINavigationController you also may want to use following code :

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

Reason is setNeedsStatusBarAppearanceUpdate() doesn't call childs preferredStatusBarStyle

CryingHippo
  • 5,026
  • 1
  • 28
  • 32
5

None of the other suggestions worked for me. I ended up getting it to work by:

  1. Setting:

    override var preferredStatusBarStyle : UIStatusBarStyle {
        return .lightContent
    }
    
  2. Calling:

    setNeedsStatusBarAppearanceUpdate()
    
Pang
  • 9,564
  • 146
  • 81
  • 122
cmilr
  • 379
  • 4
  • 13
2

My solution was as this: making an extension from the navigation controller:

extension UINavigationController {
    open override var preferredStatusBarStyle: UIStatusBarStyle {
        if let topViewController = presentedViewController{
            return topViewController.preferredStatusBarStyle
        }
        if let topViewController = viewControllers.last {
            return topViewController.preferredStatusBarStyle
        }

        return .default
    }
}

and if you have a viewController that will have another style than the style of the app , you can make this

var barStyle = UIStatusBarStyle.lightContent
override var preferredStatusBarStyle: UIStatusBarStyle{
    return barStyle
}

lets say that you app status style is .default and you want this screen to be .lightContent so barStyle will take the .lightContent as its default value, this will change the status bar style to lightContent, and then make sure when viewWillDisappear change the barStyle again to the app status bar style which in our case is .default .

this is works for me

  • Do not attempt to override methods in an extension. It is undefined behavior and [the documentation](https://docs.swift.org/swift-book/LanguageGuide/Extensions.html) states that you should not do it. – rmaddy Jul 23 '19 at 04:02