203

I'm using Xcode 8.0 beta 4.

In previous version, UIViewController have method to set the status bar style

public func preferredStatusBarStyle() -> UIStatusBarStyle

However, I found it changed to a "Get ONLY varaiable" in Swift 3.

public var preferredStatusBarStyle: UIStatusBarStyle { get } 

How can provide the style to use in my UIViewController?

Krunal
  • 77,632
  • 48
  • 245
  • 261
Willjay
  • 6,381
  • 4
  • 33
  • 58

33 Answers33

515

[UPDATED] For Xcode 10+ & Swift 4.2+

This is the preferred method for iOS 7 and higher

In your application's Info.plist, set View controller-based status bar appearance to YES.

Override preferredStatusBarStyle (Apple docs) in each of your view controllers. For example:

override var preferredStatusBarStyle: UIStatusBarStyle {     
      return .lightContent
}

If you have preferredStatusBarStyle returning a different preferred status bar style based on something that changes inside of your view controller (for example, whether the scroll position or whether a displayed image is dark), then you will want to call setNeedsStatusBarAppearanceUpdate() when that state changes.

iOS before version 7, deprecated method

Apple has deprecated this, so it will be removed in the future. Use the above method so that you don't have to rewrite it when the next iOS version is released.

If your application will support In your application's Info.plist, set View controller-based status bar appearance to NO.

In appDelegate.swift, the didFinishLaunchingWithOptions function, add:

UIApplication.shared.statusBarStyle = .lightContent

For Navigation Controller

If you use a navigation controller and you want the preferred status bar style of each view controller to be used and set View controller-based status bar appearance to YES in your application's info.plist

extension UINavigationController {
   open override var preferredStatusBarStyle: UIStatusBarStyle {
      return topViewController?.preferredStatusBarStyle ?? .default
   }
}
PRAVEEN
  • 5,905
  • 4
  • 16
  • 32
  • 4
    Works for me. Forgot to insert the new setting into Info.plist first. – falsecrypt Sep 07 '17 at 12:37
  • 1
    @LightMan the uiapplication statusBarStyle is not deprecated, I used this in iOS 11 and it works. – Sushobhit Oct 27 '17 at 07:13
  • 1
    @Sushobhit setStatusBarStyle was deprecated in iOS 9, as used in this answer. But you still have UIApplication.statusBarStyle as a read only property. – LightMan Oct 27 '17 at 11:32
  • Yes, [docs](https://developer.apple.com/documentation/uikit/uiapplication/1622988-statusbarstyle#) show this was depreciated in iOS 9. – wardw Oct 28 '17 at 13:59
  • 1
    There are times where you want to be able to set it programmatically due to the color of each view. – Alex Cavazos Nov 08 '17 at 19:26
  • 1
    Note that this doesn't work for vc's embedded in nav controllers: change the bar style of the nav controller instead. – Pranav Kasetti Dec 27 '17 at 11:35
  • 9
    You could also remove the line in appDelegate.swift and go to Target -> General -> Deployment Info -> Status Bar Style -> Light – Robert Veringa Jun 12 '18 at 12:22
  • the delegate line is what i was missing, setting it from project settings didnt worked – Abdul Waheed Sep 04 '18 at 09:14
  • In xcode 10, you now get a warning that this method was deprecated in iOS 9. See Abizern's answer for the now recommended method. `Setter for 'statusBarStyle' was deprecated in iOS 9.0: Use -[UIViewController preferredStatusBarStyle]` – zwilf Sep 28 '18 at 22:46
  • I was getting: > Overriding var must be as accessible as its enclosing type Which is fixed by adding `public` like: override public var preferredStatusBarStyle: UIStatusBarStyle { get { return .lightContent } } On Swift3 iOS10. – James BH Jan 31 '17 at 10:28
178

Latest Update (Xcode 10+ / Swift 4.2+)

This article is left intact for anyone willing to understand the logic behind different approaches that were present for the past several years. Meanwhile, as of Xcode 10, Swift 4.2 first approach is deprecated and is no longer supported (i.e. will not take effect if you try to employ it). It's still referred for your information to better understand the reasoning behind Plist.info flag and customizing practice.

Important clarification

It is very important to understand two approaches to customizing the status bar appearance. They are different and should not be mixed.

First approach – one color for whole app (DEPRECATED since iOS7)

In info.plist you find or create a key called

View controller-based status bar appearance

and set it to NO.

What it does? It essentially establishes a setting that says that in your application, status bar appearance is not defined individually by each view controller. This is super important to understand. This means that you have uniform setting for entire app, for all screens. There are two settings: default, which is black text on white background, or lightContent, which is white text on black background.

To set one of these up (one setting for all screens):

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    application.statusBarStyle = .lightContent // .default
    return true
}

This way you won't need to reestablish this setting on each view controller. However, you can always resort to this method to voluntarily change appearance.

Second approach – individual color for each view controller

This is the opposite. To make it work, go ahead to info.plist and set

View controller-based status bar appearance

to YES

This way, whenever a new view controller is open, status bar style is set individually if you insert this implementation in each UIViewController instance you need:

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

You have the same as in first, set either dark or light style for statusbar, individual to each view controller.

This property is fetched by UIKit in two scenarios:

  1. Upon initialization of the screen, when UI is being prepared.
  2. Upon calling setNeedsStatusBarAppearanceUpdate() in the code.

In latter case, you are eligible to manipulate the statusbar appearance by the following code:

var isDark = false {
    didSet {
        setNeedsStatusBarAppearanceUpdate()
    }
}

override var preferredStatusBarStyle: UIStatusBarStyle {
    return isDark ? .lightContent : .default
}

func toggleAppearance() {
   isDark.toggle()
}

Then, whenever you call toggleAppearance(), statusbar style change will be triggered.

Third approach – Hack!

There's a hack which allows to access statusbar directly:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    
    if let statusBar = UIApplication.shared.value(forKey: "statusBar") as? UIView {
        statusBar.backgroundColor = UIColor.blue
    }
    
    return true
}

Why hack? If you need status bar color other than black or white, you use undocumented API. You get statusBar object using KVC and set its background color. Object you get this way is UIStatusBar, which is derived from UIView and thus naturally supports backgroundColor property. This is dirty, not legal way, but so far it's the only way to set up custom color for statusbar (not taking into account UINavigationBar approach, which allows to customize navbar+statusbar appearance altogether). It may well lead your app to being rejected. But maybe you're lucky. And if you are, in certain complex circumstances (like hierarchy of nested, child navigation and view controllers) this may be pretty much the only, or at least the less troublesome way to customize statusbar appearance (for example, to make it transparent)

Xcode 10+, Swift 4.2

There are no alternatives any more: developer should let each view controller define statusbar appearance, by setting the flag to YES (or omitting this action, because it's YES by default) and following above instructions.


Bonus

Hack-based solution you might (although not encouraged to) use in complex circumstances in order to voluntarily change statusbar appearance at any stage. Color-wise, the following extension method does exactly what you could have done with regular approach. You can adjust it to your needs.

extension UIViewController {
    func setStatusBarStyle(_ style: UIStatusBarStyle) {
        if let statusBar = UIApplication.shared.value(forKey: "statusBar") as? UIView {
            statusBar.backgroundColor = style == .lightContent ? UIColor.black : .white
            statusBar.setValue(style == .lightContent ? UIColor.white : .black, forKey: "foregroundColor")
        }
    }
}
Community
  • 1
  • 1
Hexfire
  • 5,945
  • 8
  • 32
  • 42
  • 2
    Once you have the status bar, you could also do this: statusBar.setValue(UIColor.red, forKey: "foregroundColor"); or use any existing key to set any property that is available for UIStatusBar but not for UIView – Mark Sep 18 '18 at 08:41
  • application.statusBarStyle = .lightContent this approach is generally since iOS9 >Setter for 'statusBarStyle' was deprecated in iOS 9.0: Use -[UIViewController preferredStatusBarStyle] the wait to go is for UIViewController – toxicsun Nov 14 '18 at 13:28
  • This is the only it works here when changing the app's color theme. However, it seems, once this has been set, you always have to reset it when switching view controllers. The preferredStatusBarStyle() method is ignored from here on (even with the proper setting in info.plist). – nontomatic Mar 28 '19 at 09:09
  • 2
    This answer is more descriptive compared to others. – ViruMax Sep 05 '19 at 05:59
  • 3
    Bonus solution is broken in iOS 13.1 – ViruMax Sep 17 '19 at 02:39
  • Is it possible to set the status bar style for the launch screen? You can't set a custom class for the launch screen view controller. – Indiana Kernick Feb 03 '21 at 03:35
132

You could try to override the value returned, rather than setting it. The method is declared as { get }, so just provide a getter:

 override var preferredStatusBarStyle: UIStatusBarStyle {
    return .lightContent
}

If you set this conditionally, you'll need to call setNeedsStatusBarAppearanceUpdate() so it'll animate the change when you're ready

iwasrobbed
  • 46,496
  • 21
  • 150
  • 195
Abizern
  • 146,289
  • 39
  • 203
  • 257
  • 2
    This is a better approach as you can choose `prefersStatusBarHidden` for some of your views. If you are going with `UIApplication.shared.statusBarStyle` you'll be stuck with it. – superarts.org Apr 18 '18 at 02:23
110

Swift 3 & 4, iOS 10 & 11, Xcode 9 & 10
For me, this method doesn't work:

override var preferredStatusBarStyle: UIStatusBarStyle {
    return .lightContent
}

when I used to each view controller, but this worked:

  • In file info.list, add row: View controller-based status bar appearance and set to NO

  • Next in appdelegate:

    UIApplication.shared.statusBarStyle = .lightContent
    
Gracu
  • 1,132
  • 1
  • 7
  • 10
51

Xcode 10 or later

Tested in Swift 5

No code required just follow below steps.

If you want to change the status bar in the whole app.

  1. Select Project from Project Navigator (left side panel).
  2. Select target.
  3. Select General tab.
  4. Find Deployment info.
  5. Change status bar style to Light (for dark background "Light", Light background "Default")

Don't forget info.plist changes

  1. Select Info tab
  2. Add this key into your plist file "View controller-based status bar appearance" = NO

Run your project and check it.

My project in swift 5 and Xcode 10.2 & 11.0

Community
  • 1
  • 1
Vivek
  • 4,916
  • 35
  • 40
40

If you want to change the statusBar's color to white, for all of the views contained in a UINavigationController, add this inside AppDelegate:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.

    UINavigationBar.appearance().barStyle = .blackOpaque
    return true
}

This code:

override var preferredStatusBarStyle: UIStatusBarStyle {
    return .lightContent
}

does not work for UIViewControllers contained in a UINavigationController, because the compiler looks for the statusBarStyle of the UINavigationController, not for the statusBarStyle of the ViewControllers contained by it.

Hope this helps those who haven't succeeded with the accepted answer!

Mr. Xcoder
  • 4,719
  • 5
  • 26
  • 44
27

If you want to change the status bar style any time after the view has appeared you can use this:

  • In file info.list add row: View controller-based status bar appearance and set it to YES

    var viewIsDark = Bool()
    
    func makeViewDark() {
    
        viewIsDark = true
        setNeedsStatusBarAppearanceUpdate()
    }
    
    func makeViewLight() {
    
        viewIsDark = false
        setNeedsStatusBarAppearanceUpdate()
    }
    
    override var preferredStatusBarStyle: UIStatusBarStyle {
    
        if viewIsDark {
            return .lightContent 
        } else {
            return .default 
        } 
    }
    
alex oliveira
  • 491
  • 5
  • 6
  • 1
    And `If you call this method within an animation block, the changes are animated along with the rest of the animation block.` – Alexandre G Jul 03 '18 at 08:41
25

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

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

In your appdelegate class, in didFinishLaunchingWithOptions method before return.

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

change backgroundColor and statusBarStyle as per requirement.

Himanshu padia
  • 7,428
  • 1
  • 47
  • 45
15

You can also do this in storyboard

  1. Create a new entry in info.plist "View controller-based status bar appearance" set it to "YES".
  2. Go to your storyboard and then select the navigation controller that you want to change. Click on the navigation bar from Storyboard document outline section (left panel on storyboard)
  3. Go to the right panel and click the attributes section
  4. Under the Navigation Bar section you will see style. Select the style you would like (default is for black and black is for white)

You will have to do this for each navigation controller you have. However, any views under that navigation controller will change all the view's status bars style/color to the one you just selected. I find this option better because you can see your results instantly and do not have to add extra lines of code in every view controller.

enter image description here

(Done with Xcode 8.3.3 in an all Swift project)

Bryan Norden
  • 2,397
  • 18
  • 22
  • "View controller-based status bar appearance" should set to "NO" – Willjay Jul 25 '17 at 08:26
  • 3
    Very clean way to set the status bar style according to the View Controller content, which is the correct way instead of just setting `View controller-based status bar appearance = NO` and having to use only light or dark style in the entire app. It's a shame that this "Codeless" way works only in Navigation Controller, Apple should consider adding another field for setting this option inside any View Controller instance. – aldoram5 Sep 20 '17 at 14:18
15

For people looking to change status bar for all viewcontrollers on: iOS 11, Swfit 4/5 solution is pretty easy.

1) Info.plist add:

View controller-based status bar appearance -> NO

2) Left side of XCode slect project > Targets > Select your project > Under General > Deployment Info > Select Status Bar Style: Light

If you want to change status bar only for one viewcontroller, on viewDidLoad add:

2.1) Info.plist

View controller-based status bar appearance -> YES

2.2)

override var preferredStatusBarStyle : UIStatusBarStyle {
    return .lightContent
}

Objective-C (or react native) changing from App Delegate:

1) Info.plist add:

View controller-based status bar appearance -> NO

2) AppDelegate -> didFinishLaunchingWithOptions

[[UIApplication sharedApplication] setStatusBarHidden:NO animated:YES];
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDarkContent animated:YES];

Changing status bar do not work trying to do push(navigation controllers), only on presenting modally viewcontrollers.

Egzon P.
  • 4,498
  • 3
  • 32
  • 31
14

Swift 5

To add more detail for PRAVEEN's answer at https://stackoverflow.com/a/40066798/2082851, I would like to provide my implementation. It supports the flexibility to customize each controller's status bar.

In overall, we will create a BaseViewController which handle the statusBarStyle property in all the case. When you create a new controller, make it as subclass of this base controller.

Whenever you want to change the status appearance, you only need to update this property. The status bar style will be updated immediately.

Implementation

class BaseViewController: UIViewController {

    var statusBarStyle: UIStatusBarStyle = .default {
        didSet {
            setNeedsStatusBarAppearanceUpdate()
        }
    }

    override var preferredStatusBarStyle: UIStatusBarStyle {
        return statusBarStyle
    }
}

Demo

class ViewController: BaseViewController, UIScrollViewDelegate {

    let scrollView = UIScrollView()
    ... 
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        UIView.animate(withDuration: 0.3) {
            if scrollView.contentOffset.y > 30 {
                self.statusBarStyle = .darkContent
            } else {
                self.statusBarStyle = .lightContent
            }
        }
    }
}

enter image description here

2. UINavigationController

For UINavigationController, it is a special case, which you can follow either solutions:

Solution A: Override with message dispatch

Since UINavigationController is an NSObject and inherit from ObjectiveC, its methods are message dispatch and you can override them.

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

Solution B: Create UINavigationController subclass

If you already have a custom UINavigationController (which usually need to control more requirements), this is the best solution for you.

final class NavigationController: UINavigationController {
    override var preferredStatusBarStyle: UIStatusBarStyle {
        return topViewController?.preferredStatusBarStyle ?? super.preferredStatusBarStyle
    }
}
Zack Shapiro
  • 6,648
  • 17
  • 83
  • 151
nahung89
  • 7,745
  • 3
  • 38
  • 40
10

First step you need add a row with key: View controller-based status bar appearance and value NO to Info.plist file. After that, add 2 functions in your controller to specific only that controller will effect:

override func viewWillAppear(_ animated: Bool) {
       super.viewWillAppear(animated)
       UIApplication.shared.statusBarStyle = .lightContent
}

override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        UIApplication.shared.statusBarStyle = .default    
}
javimuu
  • 1,829
  • 1
  • 18
  • 29
10
  1. Chose Light Contententer image description here

  2. Add View controller-based status bar appearance with NO to .plist enter image description here

J A S K I E R
  • 1,976
  • 3
  • 24
  • 42
8

There seems to be a small issue about the status bar text colour when dealing with navigation bars.

If you want the .plist entry View controller-based status bar appearance set to YES, it sometimes won't work when you have a coloured nav bar.

For example:

override func viewWillAppear(_ animated: Bool) {
    let nav = self.navigationController?.navigationBar
    nav?.barTintColor = .red
    nav?.tintColor = .white
    nav?.titleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white]
    setNeedsStatusBarAppearanceUpdate()
}

and

override var preferredStatusBarStyle: UIStatusBarStyle {return .lightContent}

The code above won't work even if you have set the following in the AppDelegate:

UIApplication.shared.statusBarStyle = .lightContent

For those still struggling, apparently it somehow judges if the status bar needs to be light or dark by the styles in the nav bar. So, I managed to fix this by adding the following line in viewWillAppear:

nav?.barStyle = UIBarStyle.black

When the bar style is black, then it listens to your overridden variable. Hope this helps someone :)

nCr78
  • 460
  • 7
  • 9
7

Xcode 8.3.1, Swift 3.1

  1. Create a new entry in info.plist "View controller-based status bar appearance" set it to "NO".

  2. Open AppDelegate.swift and add these lines in "didFinishLaunchingWithOptions" method:

application.statusBarStyle = .lightContent

joemalski
  • 416
  • 6
  • 15
7

Swift 3

In Info.plist add a row called "View controller-based status bar appearance" and set its value to No.

class YourViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

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

    }

}
youareawaitress
  • 387
  • 2
  • 17
7

To add to the great asnwer by @Krunal https://stackoverflow.com/a/49552326/4697535

In case you are using a UINavigationController, the preferredStatusBarStyle will have no effect on the UIViewController.

Xcode 10 and Swift 4.

Set a custom UINavigationController

Example:

class LightNavigationController: UINavigationController {

   open override var preferredStatusBarStyle: UIStatusBarStyle {
       return .lightContent
   }
}

Use an extension for an app level solution:

extension UINavigationController {

  open override var preferredStatusBarStyle: UIStatusBarStyle {
      guard let index = tabBarController?.selectedIndex else { return .default }
      switch index {
      case 0, 1, 2: return .lightContent // set lightContent for tabs 0-2
      default: return .default // set dark for tab 3
      }
  }
}
Tal Zion
  • 6,308
  • 3
  • 50
  • 73
6

Swift 4+

for white statusbar text:

navigationController.navigationBar.barStyle = .blackTranslucent
Ahmadreza
  • 6,950
  • 5
  • 50
  • 69
6

Here is Apple Guidelines/Instruction about status bar style change.

If you want to set status bar style, application level then set UIViewControllerBasedStatusBarAppearance to NO in your .plist file. And in your appdelegate > didFinishLaunchingWithOptions add following ine (programatically you can do it from app delegate).

Objective C

[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent animated:YES];

Swift

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    application.statusBarStyle = .lightContent
    return true
}

if you wan to set status bar style, at view controller level then follow these steps:

  1. Set the UIViewControllerBasedStatusBarAppearance to YES in the .plist file, if you need to set status bar style at UIViewController level only.
  2. In the viewDidLoad add function - setNeedsStatusBarAppearanceUpdate

  3. override preferredStatusBarStyle in your view controller.

Objective C

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self setNeedsStatusBarAppearanceUpdate];
}

- (UIStatusBarStyle)preferredStatusBarStyle
{
    return UIStatusBarStyleLightContent;
}

Swift

override func viewDidLoad() {
    super.viewDidLoad()
    self.setNeedsStatusBarAppearanceUpdate()
}

override var preferredStatusBarStyle: UIStatusBarStyle {
    return .lightContent
}

Set value of .plist according to status bar style setup level.

enter image description here

Krunal
  • 77,632
  • 48
  • 245
  • 261
5

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
}
Anthony
  • 804
  • 3
  • 12
  • 32
Karthick C
  • 1,519
  • 17
  • 16
4

iOS 11.2

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.

    UINavigationBar.appearance().barStyle = .black

    return true
}
Satish Babariya
  • 3,062
  • 1
  • 15
  • 29
4

If you're using modal presentation you need to set:

viewController.modalPresentationCapturesStatusBarAppearance = true
3

This worked for me

Set View controller-based status bar appearance into NO in plist then In UIViewController viewDidAppear just added the following line

UIApplication.shared.setStatusBarStyle(UIStatusBarStyle.lightContent, animated: true)
Anshad Rasheed
  • 2,526
  • 1
  • 14
  • 32
3

swift 3

if View controller-based status bar appearance = YES in Info.plist

then use this extension for all NavigationController

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

if there is no UINavigationController and only have UIViewController then use Below code:

    extension UIViewController
    {
        override open var preferredStatusBarStyle: UIStatusBarStyle {
        return .lightContent
         }
     }
Datt Patel
  • 1,203
  • 1
  • 11
  • 10
  • 2
    Doesn't work for me. I get the errors "Property does not override any property from its superclass" and "Getter for 'preferredStatusBarStyle' with Objective-C selector 'preferredStatusBarStyle' conflicts with previous declaration with the same Objective-C selector". – Theo Nov 18 '17 at 14:47
  • Thanks for this, after 20 different attempts and a few combinations of items to try this is the way to set the status bar color. I just had to remember to call setNeedsStatusBarAppearanceUpdate() when I wanted to change the color as I was adding in a night mode and black on black simply wasn't working. – Stu P. Nov 27 '17 at 03:20
3

I was struggling with this too, so if you are presenting a FULLSCREEN modal view controller, make sure to set .modalPresentationStyle as .fullscreen and then, on your presenting view controller, just override .preferredStatusBarStyle to .lightContent.

So:

let navigationController = UINavigationController(rootViewController: viewController)
navigationController.modalPresentationStyle = .fullScreen // <=== make sure to set navigation modal presentation style
present(navigationController, animated: true, completion: nil)

on your custom view controller, override status bar style:

    override var preferredStatusBarStyle: UIStatusBarStyle {
        .lightContent
    }
Vinh Nguyen
  • 816
  • 1
  • 13
  • 27
2

You can using a bool property named "shouldStatusBarDark" to toggle you status bar color. And you also could update its value to change the status bar color when you scrolling.

 var shouldStatusBarDark = false {
     didSet {
         setNeedsStatusBarAppearanceUpdate()
     }
 }

 override var preferredStatusBarStyle: UIStatusBarStyle {
     return shouldStatusBarDark ? .default : .lightContent
 }

 func scrollViewDidScroll(_ scrollView: UIScrollView) {
     let offSetY = scrollView.contentOffset.y
     if offSetY > 50 {
         UIView.animate(withDuration: 0.4, animations: {
             self.navView.alpha = 1
             self.shouldStatusBarDark = true
         })
     } else {
         UIView.animate(withDuration: 0.4, animations: {
             self.navView.alpha = 0
             self.shouldStatusBarDark = false
         })
     }
 }
Stephen Rauch
  • 47,830
  • 31
  • 106
  • 135
tiantong
  • 104
  • 6
2

Most of these answers are the same thing re-hashed, but none of them actually address the launch screen for me when using a dark background.

I got around this with the following in my info.plist which produced a light styled status bar.

<key>UIStatusBarStyle</key>
<string>UIStatusBarStyleLightContent</string>
CodeBender
  • 35,668
  • 12
  • 125
  • 132
2

If you are receiving the warning: Setter for 'statusBarStyle' was deprecated in iOS 9.0: Use -[UIViewController preferredStatusBarStyle], then to set the status bar to light or dark use the following code:

//To set the status bar to white
self.navigationController?.navigationBar.barStyle = .black //or .blackTranslucent

//To set the status bar to black
self.navigationController?.navigationBar.barStyle = .default

This will not make your navBar change it purely indicates the style and therefore changes the status bar accordingly.

NB. You need to ensure that you set in your info.plist.

View controller-based status bar appearance to YES
Richard Hope
  • 251
  • 3
  • 6
2

In iOS 13 you can use .darkContent UIStatusBarStyle property to display dark status bar

2

If you still unable to change the status bar style base on the method

override var preferredStatusBarStyle: UIStatusBarStyle {
    return .lightContent
}

You may try using this method:

override viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    navigationController?.navigationBar.barStyle = .black
}
Jin
  • 665
  • 1
  • 7
  • 15
0

For objective C just add this line in your application didFinishLaunch method

UIApplication.sharedApplication.statusBarStyle = UIStatusBarStyleLightContent;
Asfand Shabbir
  • 1,234
  • 13
  • 9
0

using WebkitView

Swift 9.3 iOS 11.3

import UIKit
import WebKit

class ViewController: UIViewController, WKNavigationDelegate, WKUIDelegate {

    @IBOutlet weak var webView: WKWebView!
    var hideStatusBar = true

    override func loadView() {
        let webConfiguration = WKWebViewConfiguration()
        webView = WKWebView(frame: .zero, configuration: webConfiguration)
        webView.uiDelegate = self
        view = webView
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        self.setNeedsStatusBarAppearanceUpdate()
        let myURL = URL(string: "https://www.apple.com/")
        let myRequest = URLRequest(url: myURL!)
        UIApplication.shared.statusBarView?.backgroundColor = UIColor.red

         webView.load(myRequest)

    }
}

extension UIApplication {

    var statusBarView: UIView? {
        return value(forKey: "statusBar") as? UIView
    }

}
Oracular Man
  • 1,060
  • 11
  • 15
  • 3
    Swift 9.3? Wrong year, Marty – iOS Unit Jun 22 '18 at 15:45
  • I recommend to stay away of using private API for exaple "statusBar". Apple makes changes in API every time to time! And when apple changes that API your app may crash and it will not change the status bar any more. This will make you to search again for another solution. – Egzon P. Jan 19 '19 at 00:30
-1

Swift 3

To set the same appearance of navigation Bar across your app, you can do this in AppDelegate.swift:

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

        setupNavigationBarAppearence()
        return true
    }



private func setupNavigationBarAppearence(){
        let navigationBarAppearace = UINavigationBar.appearance()
        navigationBarAppearace.isTranslucent = false
        //nav bar color
        navigationBarAppearace.barTintColor = UIColor.primaryColor()
        //SETS navbar title string to white
        navigationBarAppearace.titleTextAttributes = [NSForegroundColorAttributeName: UIColor.white]
        //Makes the batery icon an any other icon of the device to white.
        navigationBarAppearace.barStyle = .black
    }
João Oliveira
  • 487
  • 7
  • 13