205
override func preferredStatusBarStyle() -> UIStatusBarStyle {
 return UIStatusBarStyle.LightContent;
}

Using the above code in any ViewController to set the statusBar color to White for a specific viewcontroller doesnt work in iOS8 for me. Any suggestions? Using the UIApplication.sharedApplication method, the color changes after required changes in the Info.plist for the whole app.

// Change the colour of status bar from black to white
UIApplication.sharedApplication().statusBarStyle = .LightContent

How can I just make changes to the status bar color for some required and specific ViewControllers?

Anuj
  • 6,537
  • 3
  • 18
  • 24

37 Answers37

352

After reading all the suggestions, and trying out a few things, I could get this to work for specific viewcontrollers using the following steps :

First Step:

Open your info.plist and insert a new key named "View controller-based status bar appearance" to NO

Second Step (Just an explanation, no need to implement this):

Normally we put the following code in the application(_:didFinishLaunchingWithOptions:) method of the AppDelegate,

Swift 2

UIApplication.sharedApplication().statusBarStyle = .LightContent

Swift 3

UIApplication.shared.statusBarStyle = .lightContent

but that affects the statusBarStyle of all the ViewControllers.

So, how to get this working for specific ViewControllers - Final Step:

Open the viewcontroller file where you want to change the statusBarStyle and put the following code in viewWillAppear(),

Swift 2

UIApplication.sharedApplication().statusBarStyle = .LightContent

Swift 3

UIApplication.shared.statusBarStyle = .lightContent

Also, implement the viewWillDisappear() method for that specific viewController and put the following lines of code,

Swift 2

override func viewWillDisappear(animated: Bool) {
    super.viewWillDisappear(animated)
    UIApplication.sharedApplication().statusBarStyle = UIStatusBarStyle.Default

}

Swift 3

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    UIApplication.shared.statusBarStyle = UIStatusBarStyle.default
}

This step will first change the statusBarStyle for the specific viewcontroller and then change it back to default when the specific viewcontroller disappears. Not implementing the viewWillDisappear() will change the statusBarStyle permanently to the new defined value of UIStatusBarStyle.LightContent

Thiha Aung
  • 4,656
  • 7
  • 34
  • 73
Anuj
  • 6,537
  • 3
  • 18
  • 24
  • 4
    Note that if you set `Status bar is initially hidden = YES` in info.plist file, "View controller-based status bar appearance = NO" will cause the status bar become hidden. – xi.lin Aug 20 '15 at 09:30
  • 14
    If you are changing back to `UIStatusBarStyle.Default` using `viewWillDisappear()`, you should be using `viewWillAppear()` to initialize it, rather than `viewDidLoad()`.... otherwise if you come back to that view without it having to re-load, you won't see the `StatusBarStyle` you are expecting. – William GP Apr 03 '16 at 05:38
  • Note you can use `UIApplication.sharedApplication().setStatusBarStyle()` if you want to animate the statue bar's changes – He Yifei 何一非 Sep 03 '16 at 02:09
  • Works great! Thank you – Gilad Brunfman Oct 17 '16 at 12:58
  • 7
    **For Swift 3:** `UIApplication.shared.statusBarStyle = .lightContent` – ibrahimyilmaz Nov 18 '16 at 12:23
  • 5
    It's still not clear how you change the color of the status bar – DoruChidean Sep 06 '17 at 11:37
  • 4
    Guys, its deprecated from iOS 9 – byJeevan Mar 13 '19 at 18:41
  • **for iOS 13 and up** add and set `NO` for `UIViewControllerBasedStatusBarAppearance` key in Info.plist file, and than set **Status Bar Style** to **Light Content** in **General** tab from **project target settings.** – asilturk Feb 23 '20 at 14:51
130

(As of August 25, 2020)

Swift 5, Swift 4.2, Swift 4

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    setNeedsStatusBarAppearanceUpdate()
}
override var preferredStatusBarStyle: UIStatusBarStyle {
    .lightContent
}
BennyTheNerd
  • 3,402
  • 1
  • 19
  • 16
  • 7
    Make sure to call `super.viewWillAppear` if you're copy and pasting this code – Stephen Silber Nov 17 '16 at 19:37
  • Edited to included super.viewWillAppear(). Thanks @StephenSilber for the tip! – BennyTheNerd May 05 '17 at 19:24
  • you have to override the preferredStatusStyle or it won't work. thanks for pointing that out. +1 – Alix Aug 10 '17 at 17:01
  • 3
    Using `UIApplication.shared.statusBarStyle = .lightContent` results in this compiler warning: Setter for 'statusBarStyle' was deprecated in iOS 9.0: Use -[UIViewController preferredStatusBarStyle] – airowe Nov 13 '18 at 14:20
  • 3
    In your application's Info.plist, set "View controller-based status bar appearance" to YES – IvanPavliuk Mar 20 '19 at 13:07
  • no worky if set otherwise elsewhere in the code. Also not the right answer since the OP wants this per given view – Alex Kornhauser Dec 23 '19 at 23:28
  • @Alex, this is the way of doing per view. Please don't add #fakenews in the comments – BennyTheNerd Jan 10 '20 at 01:54
  • how is this even a write answer? question is to change color of status bar not style... – jayant rawat Feb 13 '20 at 06:55
  • @jayantrawat, welcome to Swift and Xcode. The way to change the "color" is to change the style. Apple provides 2 color options for status bars ... one is white, the other is black. Both are given their own respective "style" type – BennyTheNerd Mar 05 '20 at 02:19
  • Does not work if your view controllers are embedded In a Root Navigation controller. If controller A is white, and push to controller B, this won't work, it will remain white. – Amit May 22 '20 at 08:49
  • If you present your view controller modally wrapped in navigation controller you need to set `modalPresentationCapturesStatusBarAppearance = true` for navigation controller – malex Nov 08 '20 at 20:54
40

Swift 4.2 solution with NavigationController

First Step:

Open your info.plist and insert a new key named "View controller-based status bar appearance" or UIViewControllerBasedStatusBarAppearance to YES to let each VC use their own status property.

Second Step

In each VC, override the preferredStatusBarStyle property like this :

override var preferredStatusBarStyle : UIStatusBarStyle {
    return .lightContent //.default for black style
}

Last step

Override the preferredStatusBarStyle property in your custom NavigationController class :

class NavigationController : UINavigationController {

override var preferredStatusBarStyle : UIStatusBarStyle {

    if let topVC = viewControllers.last {
        //return the status property of each VC, look at step 2
        return topVC.preferredStatusBarStyle  
    }

    return .default
}
WINSergey
  • 1,734
  • 22
  • 36
guillama
  • 411
  • 4
  • 6
  • 1
    This is only the way how to achieve expected result using Navigation Controller and your own controllers. Also you could do this way for prefersStatusBarHidden as I did for my project :) – atereshkov Jul 29 '19 at 09:04
30

I followed this tutorial and it worked for me. However, I am not sure if there are any caveats.

https://coderwall.com/p/dyqrfa/customize-navigation-bar-appearance-with-swift

  • Open your info.plist and set UIViewControllerBasedStatusBarAppearance to false.
  • In the first function in AppDelegate.swift, which contains didFinishLaunchingWithOptions, set the color you want.

UIApplication.sharedApplication().statusBarStyle = UIStatusBarStyle.LightContent

  • Swift 3 Update *

    UIApplication.shared.statusBarStyle = .lightContent

Gad
  • 2,741
  • 22
  • 35
chris_s
  • 961
  • 4
  • 11
  • 27
  • 11
    how is that specific to each view controller – Yarneo Feb 13 '15 at 21:29
  • 4
    Exactly, this is for the complete app, and that is not the question. – Anuj Feb 14 '15 at 06:33
  • 3
    I'm using iOS 8 Swift and xCode 6.1.1 and just following these two steps doesn't work. You also need to add `UIApplication.sharedApplication().statusBarHidden = false` to the AppDelegate.swift didFinishLauchingWithOptions – Ahmad Amin Feb 17 '15 at 22:15
  • This set it for the entire application. For specific view controllers, see the first answer. It worked for me. – Akshar Patel Apr 06 '16 at 11:45
  • Setter for 'statusBarStyle' was deprecated in iOS 9.0: Use -[UIViewController preferredStatusBarStyle] – J A S K I E R Jan 10 '20 at 08:32
23

There's a billion answers here so I thought why not add another in the form of an extension (with help from @Cœur)

Swift 3

Extension:

extension UIApplication {
    class var statusBarBackgroundColor: UIColor? {
        get {
            return (shared.value(forKey: "statusBar") as? UIView)?.backgroundColor
        } set {
            (shared.value(forKey: "statusBar") as? UIView)?.backgroundColor = newValue
        }
    }
}

Implementation:

UIApplication.statusBarBackgroundColor = .blue
John R Perry
  • 3,357
  • 1
  • 30
  • 46
  • 2
    Please note that this approach could be considered accessing a private API, and may mean your app will be rejected by Apple. – JWhitey Oct 18 '18 at 16:48
  • Or at least it's dependent on Apple's implementation details and may break without warning with changes in iOS. – Chris Prince Oct 19 '18 at 19:52
20

In your Info.plist you need to define View controller-based status bar appearance to any value.

If you define it YES then you should override preferredStatusBarStyle function in each view controller.

If you define it NO then you can set style in AppDelegate using

UIApplication.sharedApplication().setStatusBarStyle(UIStatusBarStyle.LightContent, animated: true)
Nikita Khandelwal
  • 1,731
  • 14
  • 25
15
override func viewWillAppear(animated: Bool) {
    self.navigationController?.navigationBarHidden =  true

    UIApplication.sharedApplication().statusBarHidden = false
    UIApplication.sharedApplication().statusBarStyle = .LightContent

    let statusBar: UIView = UIApplication.sharedApplication().valueForKey("statusBar") as! UIView
    if statusBar.respondsToSelector("setBackgroundColor:") {
        statusBar.backgroundColor = UIColor.redColor()
    }

}
A.G
  • 13,048
  • 84
  • 61
15

Swift 3

let statusBar: UIView = UIApplication.shared.value(forKey: "statusBar") as! UIView
if statusBar.responds(to: #selector(setter: UIView.backgroundColor)) {
  statusBar.backgroundColor = UIColor.black
} 

That's the solution for setting background color of the status bar for specific view controller.

Chris Tsitsaris
  • 540
  • 10
  • 11
13

SWIFT 2

I was able to successfully change the appearance of the status bar background by adding the following in my viewWillAppear:

let statusBar: UIView = UIApplication.sharedApplication().valueForKey("statusBar") as! UIView

    if statusBar.respondsToSelector(Selector("setBackgroundColor:")) {
        statusBar.backgroundColor = .redColor()
    }
A.J. Hernandez
  • 919
  • 11
  • 13
10

Implement preferredStatusBarStyle as you mentioned and call self.setNeedsStatusBarAppearanceUpdate() in ViewDidLoad and also in Info.plist set UIViewControllerBasedStatusBarAppearance to YES (It's YES by default)

It is not clear why it is not working.I need to check code.One other suggestion is go with working code in viewDidLoad UIApplication.sharedApplication().statusBarStyle = .LightContent and change this to default when you view get disappeared viewWillDisappear.

codester
  • 34,623
  • 10
  • 72
  • 70
  • Just implementing the first part of the answer, worked for me. However, I did not add the UIViewcontrollerBasedStatusBarAppearance in the Info.plist. It still worked. – Akshar Patel Apr 06 '16 at 11:48
10

for swift 3

.plist

View controller-based status bar appearance = NO

AppDelegate.swift

  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Custom statubar
        UIApplication.shared.isStatusBarHidden = false
        UIApplication.shared.statusBarStyle = .lightContent
        let statusBar: UIView = UIApplication.shared.value(forKey: "statusBar") as! UIView
        statusBar.backgroundColor = UIColor.gray

        return true
    }
Giang
  • 3,031
  • 26
  • 26
9

In my situation,I use storyboard to organize my view controllers.I want to change all status bar style.

You can see in picture below.

enter image description here

Stars View Controller is a CPBaseNavigationController,and CPBaseNavigationController is subclass of UINavigationController.

I try doing the next setps:

  1. In AppDelegate.swift func didFinishLaunchingWithOptions,add

    //change status bar color
    UIApplication.sharedApplication().statusBarHidden = false
    UIApplication.sharedApplication().statusBarStyle = .LightContent
    

    but no effect.

  2. In StoryBoard,find the Base Tab BarController(picture on the above).select Attributes Inspector, change the Sattus Bar attribute to Light Content.so bad,no effect.

enter image description here

  1. Last I get it.In my custom navigation controller CPBaseNavigationController,add func preferredStatusBarStyle

    override func preferredStatusBarStyle() -> UIStatusBarStyle {
       return .LightContent
    }
    

    It works well!

Besides,statusBarStyle deprecated in 9.0,you can use -[UIViewController preferredStatusBarStyle].

wenghengcong
  • 558
  • 5
  • 10
9

Swift 3

//
//  LoginController.swift
//  Swift 3
//
//  Created by The Crab on 17/01/2017.
//  Copyright © 2017 Paxi Labs. All rights reserved.
//

import UIKit

class LoginController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        setNeedsStatusBarAppearanceUpdate()

        view.backgroundColor = UIColor(red: 61/255, green: 91/255, blue: 151/255, alpha: 1)

    }

    override var preferredStatusBarStyle: UIStatusBarStyle {
        return .lightContent
    }
}
John R Perry
  • 3,357
  • 1
  • 30
  • 46
theCrab
  • 546
  • 5
  • 8
8

Works for Navigation Based Application

    var addStatusBar = UIView()
    addStatusBar.frame = CGRectMake(0, 0, UIScreen.mainScreen().bounds.width, 20);
    addStatusBar.backgroundColor = global().UIColorFromRGB(0x65b4d9)
    self.window?.rootViewController?.view .addSubview(addStatusBar)
Jio
  • 1,096
  • 1
  • 9
  • 22
8

Everything is much easier in Swift 3.0 Xcode 8

Using the code below in App Delegate file, after

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

insert this:

UINavigationBar.appearance().barStyle = .black

UINavigationBar.appearance().barTintColor = UIColor(red: 230, green: 32, blue: 31, alpha: 1.0)
Anton Russia
  • 187
  • 1
  • 2
  • 1
    Red, green and blue values are in range from 0 to 1. You have to divide them by 255 or it won't work. – Makalele Mar 03 '17 at 23:43
8

(As of June 10, 2020)

Swift 5 (Without editing .Plist file)

If you are using Storyboard, go to the NavigationController, select the navigationBar, click on the Attributes Inspector, then change the style. if you need light content (white status bar) set it anything except default lets say set style black And if you want dark content (black status bar) set it default.

The default (UIBarStyleDefault) results in the dark foreground UIStatusBarStyleDefault status bar. And UIBarStyleBlack will give a UIStatusBarStyleLightContent status bar.

Programatically

let nav = UINavigationController(rootViewController: rootViewController)

    nav.navigationBar.barStyle = .default //gives you dark Content status bar

    nav.navigationBar.barStyle = .black  //gives you light content status bar

Without Navigation Bar (Edit .Plist)

add UIViewControllerBasedStatusBarAppearance / View controller-based status bar appearance to your info.plist, and set value is true.

Override the preferredStatusBarStyle property in your Controller

class ViewController: UIViewController {
    override var preferredStatusBarStyle : UIStatusBarStyle {
        return .lightContent
    }
}
Jawad Ali
  • 11,075
  • 2
  • 25
  • 39
7

Swift 4 For specific ViewController without navigationViewController embedded just add this to your ViewController file.

override var preferredStatusBarStyle : UIStatusBarStyle {
    return .lightContent
}
Surjit Singh
  • 231
  • 3
  • 7
7

Another really easy way to make this work is just to create an extension of the UINavigationController class.

Since overriding the preferredStatusBarStyle: method wont work UNLESS we do it inside of the UINavigationController class.

    extension UINavigationController {
        open override var preferredStatusBarStyle: UIStatusBarStyle {
            return .lightContent
        }
    }
aBilal17
  • 2,392
  • 1
  • 15
  • 23
azemi
  • 129
  • 2
  • 4
5

I had some trouble with this one. I didn't really feel good about globally changing the status bar color in view did appear and then changing it back on view did disappear like the accepted answer. Believe it or not you can get this working by overriding preferredStatusBarStyle on your desired view controller. After much time this is what I did to get it working:

  1. Change View controller-based status bar appearance in your info.plist to YES.
  2. Now any full screen view controller can change the status bar style by overriding preferredStatusBarStyle.
  3. I specify full screen because this will not work for (non-full screen) modal view controllers, not without setting modal​Presentation​Captures​Status​Bar​Appearance to Yes that is.
  4. Also if you have embedded view controllers, like in a navigation controller for example, it will ask the top most view controller for status bar style. Overriding child​View​Controller​For​Status​Bar​Style and passing the embedded view controller is supposed to work but it didn't for me. So I just returned the embedded view controllers preferred status bar as the preferred status bar style. Something like this:

    override var preferredStatusBarStyle: UIStatusBarStyle {
         if let topViewController = viewControllers.last {
             return topViewController.preferredStatusBarStyle
         }
    
         return .default
    }
    
Nathan Tuggy
  • 2,239
  • 27
  • 28
  • 36
John C.
  • 329
  • 4
  • 3
  • This answer helped me! I found that for some reason my navigation controller (being presented modally) _wasn't_ implicitly asking the top-most view controller for its status bar style. So I had to subclass `UINavigationController` and override the `child​View​Controller​For​Status​Bar​Style` var in there, returning `self.topViewController`. – taber Jun 09 '18 at 07:10
4

I had set specific color (in RGB format) using below code in App Delegate file:

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

 UIApplication.sharedApplication().statusBarHidden = false
        UIApplication.sharedApplication().statusBarStyle = .LightContent

        let statusBar: UIView = UIApplication.sharedApplication().valueForKey("statusBar") as! UIView
        if statusBar.respondsToSelector(Selector("setBackgroundColor:")) {
            statusBar.backgroundColor = UIColor.init(red: 0.1, green: 0.27, blue: 0.60, alpha: 1.0)
        }

. . .
}

You also need to add below key in Info.plist file :

View controller-based status bar appearance with boolean value set to NO

Screenshot 1

Screenshot 2

Jayprakash Dubey
  • 32,447
  • 16
  • 161
  • 169
4

I can suggest you a simpler way,

  1. Just call setNeedsStatusBarAppearanceUpdate in viewDidLoad as Apple docs says,

Call this method if the view controller's status bar attributes, such as hidden/unhidden status or style, change. If you call this method within an animation block, the changes are animated along with the rest of the animation block.

  1. Implement preferredStatusBarStyle returning your preferred type.

It worked for me in iOS 10.1.

Objective C

[self setNeedsStatusBarAppearanceUpdate];

-(UIStatusBarStyle)preferredStatusBarStyle {
     return UIStatusBarStyleLightContent;
}

Swift

setNeedsStatusBarAppearanceUpdate()

var preferredStatusBarStyle: UIStatusBarStyle { 
    return .lightContent
}

I am surprised nobody pointed this out. Anyway enjoy :)

Bhaumik Desai
  • 215
  • 1
  • 9
4

Custom color for the status bar (iOS11+, Swift4+)

If you are looking for a solution how to change the status bar to your custom color, this the working solution.

let statusBarView = UIView()
view.addSubview(statusBarView)
statusBarView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
    statusBarView.topAnchor.constraint(equalTo: view.topAnchor),
    statusBarView.leftAnchor.constraint(equalTo: view.leftAnchor),
    statusBarView.rightAnchor.constraint(equalTo: view.rightAnchor),
    statusBarView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor)
])
statusBarView.backgroundColor = .blue
Tung Fam
  • 6,494
  • 4
  • 48
  • 55
4

In Swift 5 or xcode 11 and later set (View controller-based status bar appearance) key in info.plist as NO Then go to project target and select general, Set status bar style to dark or light

Mahmoud
  • 41
  • 1
3

What worked with me, in the Storyboard, go to the Navigation Controller, select the navigation bar, click on the Attributes Inspector, then change the style from default to black. That's it!

Amr
  • 1,962
  • 1
  • 11
  • 8
3

In Swift 4 or 4.2

You can add on your vc

preferredStatusBarStyle

and set return value to

.lightContent or .default

ex:

override var preferredStatusBarStyle: UIStatusBarStyle {
        return .lightContent
}
Ridho Octanio
  • 513
  • 5
  • 13
2

Swift 3.0 Update

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

        UIApplication.shared.statusBarStyle = .lightContent

        return true
    }
Dharmesh Kheni
  • 67,254
  • 32
  • 154
  • 160
Jaseibert
  • 21
  • 2
2

SWIFT 4.2 Hey, I wanted to share a solution, that worked for me that I got from a great article on this ellusive subject by Graig Grummitt.

Step 1 As others have mentioned ADD below to your PLIST

View controller-based status bar appearance YES

Step 2 in the RootViewcontroller add below

var statusBarHidden: Bool = false {
        didSet(newValue) {
            UIView.animate(withDuration: 0.1) {
                self.setNeedsStatusBarAppearanceUpdate()
            }
        }
    }

    override var prefersStatusBarHidden: Bool {
        return statusBarHidden
    }

    var vcStatusBarStyle: UIStatusBarStyle = .default {
        didSet(newValue) {
            UIView.animate(withDuration: 0.1) {
                self.setNeedsStatusBarAppearanceUpdate()
            }
        }
    }

    override var preferredStatusBarStyle: UIStatusBarStyle {
        return vcStatusbarStyle
    }

When updating either property statusBarHidden or vcStatusBarStyle it will call setNeedsStatusBarAppearanceUpdate() and will update the status bar with the new values for either prefersStatusBarHidden or preferredStatusBarStyle. In my situation I had to update these properties for the container viewcontroller, that was the parent of the visable childviewcontroller. I did this using a simple delegate method.

protocol MainViewControllerDelegate {
    func updateStatusBarStyle(statBarStayle: UIStatusBarStyle)
    func toggleStatusBar(visable: Bool)
}

Ofcourse when instantiating the childViewController(Visible VC) don't forget to set the MainViewcontroller(Container VC) as its delegate. I sometimes do. :)

childViewController.delegate = self

Then in the childViewController I just called the delegate method when needed to update the status bar.

self.delegate?.updateStatusBarStyle(statBarStayle: .default)

As mentioned above Graig Grummitt goes into more detail about this solution and also working with UINavigationControllers as well. Link here: The Mysterious Case of the Status Bar

Erik Uecke
  • 21
  • 4
1

Click on the Supporting Files group(left side top - name of your project). Navigate to Info. Click on + somewhere between lists, like below bundle name. And add "View controller-based status bar appearence" and set it to NO. Then open AppDelegate.swift and modify like this:

func application(application: UIApplication!, didFinishLaunchingWithOptions launchOptions: NSDictionary!) -> Bool {

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

return true
}

Thats it.

Goran Jakovljevic
  • 2,162
  • 1
  • 23
  • 23
1

For Xcode 10 you can create a class and put it before your viewController class, you can call this class in all view controller is needed a light content status bar...

class UIViewControllerWithLightStatusBar: UIViewController {
override var preferredStatusBarStyle: UIStatusBarStyle {
return UIStatusBarStyle.lightContent
}
}

Now change your viewController class in:

class YourViewController: UIViewControllerWithLightStatusBar {
...
}

And that's all...

Fabio
  • 3,653
  • 3
  • 16
  • 17
1

Works for Navigation Based for particular view controller in swift4

   let app = UIApplication.shared
   let statusBarHeight: CGFloat = app.statusBarFrame.size.height

   let statusbarView = UIView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: statusBarHeight))
   statusbarView.backgroundColor = UIColor.red
   view.addSubview(statusbarView)
1

WARNING


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

UIApplication.shared.statusBarStyle = .default

so 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

1

There are two situation:

1.show navigation bar

1) add1UIViewControllerBasedStatusBarAppearance / View controller-based status bar appearance to your info.plist, and set value is true.

2) Override the preferredStatusBarStyle property in your custom NavigationController class : (from @guillama)

class NavigationController : UINavigationController {

    override var preferredStatusBarStyle : UIStatusBarStyle {

    if let topVC = viewControllers.last {
        //return the status property of each VC, look at step 2
        return topVC.preferredStatusBarStyle  
    }
        return .default
    }

3) override preferredStatusBarStyle in your specific view controller:

override var preferredStatusBarStyle : UIStatusBarStyle {
    return .lightContent
}

2.hidden navigation bar

1) ditto

2) don't need second step above, you should implement third step directly.

override var preferredStatusBarStyle : UIStatusBarStyle {
    return .lightContent
}
fzh
  • 658
  • 1
  • 5
  • 13
1

I use this way in Swift 5, Swift 4.2.

Add next values to Info.plist:

UIViewControllerBasedStatusBarAppearance = YES

or

UIViewControllerBasedStatusBarAppearance = NO (to see changes)

UIStatusBarHidden = NO

UIStatusBarStyle = UIStatusBarStyleDefault (or set to UIStatusBarStyleLightContent if you want to see light status bar texts on launching)

Info.plist

Then place code below to specific view controllers where you want to see light content (to see dark texts set preferredStatusBarStyle to .darkContent).

override var preferredStatusBarStyle: UIStatusBarStyle {
    return .lightContent
}

override func viewDidLoad() {
    super.viewDidLoad()

    if let statusBar: UIView = UIApplication.shared.value(forKey: "statusBar") as? UIView {
        statusBar.backgroundColor = .sunflowerYellow
    }
}
Agisight
  • 1,634
  • 1
  • 11
  • 15
  • With this in viewDidLoad "if let statusBar: UIView = UIApplication.shared.value(forKey: "statusBar") as? UIView { statusBar.backgroundColor = .sunflowerYellow }" the program crashing – Alex Giatrakis Feb 11 '20 at 12:56
-1

As of Oct 2020, Swift 5, Xcode 12

If you want to set it to all view controllers in the app. and if your app has a navigation controller.

You can do it in the plist file as follow: plist file changes

Kaiusee
  • 1,073
  • 1
  • 10
  • 28
-2

Swift 3

In your AppDelegate file inside func application method

let statusBar: UIView = application.value(forKey: "statusBar") as! UIView
statusBar.backgroundColor = .red
Mohammed Tawfik
  • 450
  • 1
  • 7
  • 18
-2

if somebody wants to change the battery and text color of the status bar like the below image:

enter image description here

you can use the following code in the appdelegate class.

UINavigationBar.appearance().barTintColor = UIColor(red: 234.0/255.0, green: 46.0/255.0, blue: 73.0/255.0, alpha: 1.0)
UINavigationBar.appearance().tintColor = UIColor.white
UINavigationBar.appearance().titleTextAttributes = [NSAttributedString.Key.foregroundColor : UIColor.white]
Ahmed Ashraf Butt
  • 79
  • 1
  • 1
  • 11
-3

Swift 4.0 Please use this code in "didFinishLaunchingWithOptions launchOptions:" Appdelegate class

UIApplication.shared.statusBarStyle = .lightContent let statusBar: UIView = UIApplication.shared.value(forKey: "statusBar") as! UIView if statusBar.responds(to: #selector(setter: UIView.backgroundColor)){ statusBar.backgroundColor = UIColor.black }

iOS 13

 var statusBarView: UIView = UIView()
        if #available(iOS 13.0, *) {
            let tag:UInt64 = 38482458385
            if let statusBar = UIApplication.shared.keyWindow?.viewWithTag(Int(tag)) {
                statusBar.backgroundColor = UIColor.red
                statusBarView = statusBar
            } else {
                let statusBar = UIView(frame: UIApplication.shared.statusBarFrame)
                statusBar.tag = Int(tag)
                UIApplication.shared.keyWindow?.addSubview(statusBar)
                statusBarView = statusBar
            }
        } else {
            statusBarView = (UIApplication.shared.value(forKey: "statusBar") as? UIView)!
            if statusBarView.responds(to: #selector(setter: UIView.backgroundColor)){
                statusBarView.backgroundColor = UIColor.red
            }
        }
Karthick C
  • 1,483
  • 17
  • 13