87

I'm trying to change the Status Bar color in my Swift app to white, but am hitting a brick wall. I have 3 ViewControllers that are each embedded in a NavigationController (could that be the issue? I've already tried to place the code in the NavigationController class.) I've tried both of the following pieces of code in the didFinishLaunchingWithOptions of my AppDelegate.swift file but neither worked.

application.statusBarStyle = .LightContent

and

UIApplication.sharedApplication().statusBarStyle = .LightContent

All that the Docs have to say about it is that UIBarButtonStyle is an Int and gave me this enum snippet which didn't help me at all with implimentation.

enum UIStatusBarStyle : Int {
    case Default
    case LightContent
    case BlackOpaque
}

What am I missing?

davidrayowens
  • 1,562
  • 2
  • 13
  • 23

11 Answers11

148

You have two options.

If you want to continue manually setting the style of the status bar, continue doing what you're doing, but you'll need to add the following key to your info.plist file with a value of NO.

View controller-based status bar appearance

Or, if you want to continue to use view controller based status bar appearance, instead of setting the application's statusBarStyle, override the preferredStatusBarStyle property in each view controller for which you'd like to specify a status bar style.

Swift 3

override var preferredStatusBarStyle: UIStatusBarStyle {
    return .lightContent
}

Swift 2

override func preferredStatusBarStyle() -> UIStatusBarStyle {
    return UIStatusBarStyle.LightContent
}
Salman Ghumsani
  • 3,647
  • 2
  • 21
  • 34
Mick MacCallum
  • 129,200
  • 40
  • 280
  • 281
143

Swift 3.0

in AppDelegate.swift didFinishLaunchingWithOptions

UIApplication.shared.statusBarStyle = .lightContent

Info.plist

View controller-based status bar appearance -> NO

Swift 2.2

in AppDelegate.swift didFinishLaunchingWithOptions

UIApplication.sharedApplication().statusBarStyle = .LightContent

Info.plist

View controller-based status bar appearance -> NO
John R Perry
  • 3,916
  • 2
  • 38
  • 62
Maselko
  • 4,028
  • 2
  • 22
  • 21
  • 3
    sorry, this might be the simplest answer, but it's definitely not the BEST: because it just sets this one style to all and any viewControllers in the app. The behaviour has been introduced to enable finer control and apply different settings based on different view controllers (e.g. mixing light and dark contents). – auco Jun 18 '16 at 14:46
  • It's bizarre - not what the Apple docs say, but it works. Tried a bunch of other ways, including have a UIViewController based status bar, none of them worked. – n13 Nov 23 '16 at 07:04
37

You have to set the:

navigationController.navigationBar.barStyle = .black

and the text will appear in white

Nico S.
  • 3,056
  • 1
  • 30
  • 64
  • 1
    Thanks! There was nothing helped even this override func preferredStatusBarStyle() -> UIStatusBarStyle { return UIStatusBarStyle.LightContent } this really helps: navigationController.navigationBar.barStyle = .BlackTranslucent navigationController.navigationBar.translucent = true – Svitlana Jan 29 '16 at 20:34
  • Thank! You saved my day. However, BlackTranslucent is deprecated. Hence, I used navigationController.navigationBar.barStyle = .Black – hsusmita Feb 18 '16 at 08:16
  • It's perfectly working with `override var preferredStatusBarStyle: UIStatusBarStyle { return .lightContent }`. You just have to write this line in `viewDidLoad` for wrok well. Make sure keep `View controller-based status bar appearance = YES` with this solution. – Bhavin_m Jul 31 '17 at 12:11
  • seems like an overkill... just tried it and worked like this in Info.plist file: 1. Status bar style -> UIStatusBarStyleLightContent 2. View controller-based status bar appearance -> NO – raistlin Aug 13 '19 at 09:17
  • Making this change made my back button disappear. – Leon Dec 21 '20 at 13:48
21

For iOS9.x and Xcode7, just put this inside AppDelegate.swift:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

    UINavigationBar.appearance().barStyle = .Black

} 

This will automatically turn your status bar's style to .Lightcontent for all the view controllers inside a UINavigationController.

(Also, delete View controller-based status bar appearance from Info.plist to suppress the warnings you're probably seeing too!)

Biodave
  • 397
  • 4
  • 5
  • thank you. There seems to be a serious bug in iOS9. This was the only way I could turn the status bar in the initial VC white. I tried everything. I'll file an radar. – 1b0t Sep 29 '15 at 20:03
  • preferredStatusBarStyle returning UIStatusBarStyleDefault but not updating lightcontent to darkcontent for specific viewcontroller . After self.navigationController.navigationBar.barStyle=UIBarStyleDefault; in viewWillAppear worked for me . Hope this comment will help others. – Pandey_Laxman Nov 19 '15 at 12:50
  • Note that the UIStatusBarStyle has been changed to ".black" (lowercase B) in Swift 3 – brycejl Jul 30 '17 at 01:32
16

In Swift 3, status bar style has changed to a computed property in UIViewController that you can override like this:

override var preferredStatusBarStyle: UIStatusBarStyle {
   return .lightContent //or default
} 
Tunaki
  • 132,869
  • 46
  • 340
  • 423
Eric Welander
  • 560
  • 4
  • 11
13

On iOS 9 the following (setStatusBarStyle) is deprecated and you will get a warning if you go that way.

UIApplication.sharedApplication().setStatusBarStyle(UIStatusBarStyle.LightContent, animated: true)

If you want all statusBars changed in a single shot try adding the following to your Info.plist. This will also make your launch-screen status bar white. While the code above won't.

<key>UIStatusBarStyle</key>
<string>UIStatusBarStyleLightContent</string>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
GuiSoySauce
  • 1,763
  • 3
  • 24
  • 37
  • The .plist approach is correct, but setStatusBarStyle() is not necessary. 'setStatusBarStyle(_:animated:)' was deprecated in iOS 9.0: Use -[UIViewController preferredStatusBarStyle] – Bill Chan Aug 05 '16 at 14:20
  • @BillChan thanks for commenting but please read the answer gain. I already explained 'setStatusBarStyle' was deprecated. You should use preferredStatusBarStyle if you want one or another viewControllers changed. The plist approach is for who wants all viewControllers changed in a single shot. There is no right or wrong here. Just a matter of what you need to achieve. – GuiSoySauce Aug 06 '16 at 22:45
  • 1
    UIStatusBarStyle = UIStatusBarStyleLightContent (in .plist) helped my app launch with white status bar text ... Thanks!!! – Chris Allinson Jan 04 '17 at 17:11
11

for me all above dind't work until i add:

self.navigationController?.navigationBar.barStyle = .black;

so:

  1. Set UIViewControllerBasedStatusBarAppearance to YES in .plist
  2. In viewDidLoad call self.setNeedsStatusBarAppearanceUpdate();
  3. Override preferredStatusBarStyle
    override var preferredStatusBarStyle: UIStatusBarStyle { return .lightContent }
  4. In overrided method i set also the navigationBar.barStyle so final
    for light content:
    override var preferredStatusBarStyle: UIStatusBarStyle { self.navigationController?.navigationBar.barStyle = .black;//or default return .lightContent //or default }
    and for black content use default

The source from here and here.

and if this doesn't work you can try add a UINavigationController extension:

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

        return .default
    }
}
Community
  • 1
  • 1
Constantin Saulenco
  • 2,353
  • 1
  • 22
  • 44
5

Strange, using Swift 3.1 & XC8.2.1, but all of the above didn't work.

What I did, is just

extension UINavigationController
{
    override open var preferredStatusBarStyle: UIStatusBarStyle {
        get {
            return .lightContent
        }
    }
}

No Plist, no other stuff. HTH

Lord iPhonius
  • 173
  • 2
  • 11
2

In Swift 3.0 you can override a getter in ViewController for View controller-based status bar appearance:

override var preferredStatusBarStyle: UIStatusBarStyle {
    get { return .lightContent }
}
Denis Kreshikhin
  • 8,856
  • 9
  • 52
  • 84
1

Don't edit your Info.plist. Add this to your ViewController.swift:

override func preferredStatusBarStyle() -> UIStatusBarStyle {
    return UIStatusBarStyle.LightContent
}
Sev
  • 45
  • 5
1

Step 1. Add to info.plist View controller-based status bar appearance -> NO

Step 2. Add code in method where you need to change status bar color:

UIApplication.shared.statusBarStyle = .lightContent //(or .default)
setNeedsStatusBarAppearanceUpdate()

Key line of code: setNeedsStatusBarAppearanceUpdate()

Igor
  • 12,165
  • 4
  • 57
  • 73