Oleksandr Veremchuk
Oleksandr Veremchuk

Reputation: 11085

How to change Status Bar text color in iOS

My application has a dark background, but in iOS 7 the status bar became transparent. So I can't see anything there, only the green battery indicator in the corner. How can I change the status bar text color to white like it is on the home screen?

Upvotes: 1096

Views: 676793

Answers (30)

This answer is with the help of hackingwithswift website

for iOS (13, *)

Some Time we need different colour of status bar, for example for one ViewController we need the black status bar, and for the second ViewController we need the white status bar. Now what we have to do? We need to add this peace of code in ViewController

    // MARK: - Variables
    override var preferredStatusBarStyle: UIStatusBarStyle {
        return .lightContent
    }
    // MARK: - View Life Cycle
    override func viewDidAppear(_ animated: Bool) {
        setNeedsStatusBarAppearanceUpdate()
    }

This code will change the light or White colour of status bar in that particular ViewController. We can change it to .dark in preferredStatusBarStyle

For more details visits hackingwithswift

Edited

Update for Xcode 15.2

Need to add below line in viewDidAppear before setNeedsStatusBarAppearanceUpdate()

    navigationController?.navigationBar.barStyle = .black

So the Updated code will be for viewDidAppear

        // MARK: - View Life Cycle
        override func viewDidAppear(_ animated: Bool) {
            navigationController?.navigationBar.barStyle = .black
            setNeedsStatusBarAppearanceUpdate()
        }

Upvotes: 3

Srinivasan_iOS
Srinivasan_iOS

Reputation: 1088

Its working fine and simple code for each view controller

override var preferredStatusBarStyle: UIStatusBarStyle {
        return .white
    }

Below, we are using different styles for each ViewController. You can set the status bar color with a simple override method.

enter image description here

Don't forget to set the View controller-based status bar appearance to YES in your Info.plist.

Upvotes: 0

Saranjith
Saranjith

Reputation: 11577

Update for iOS 17+

Considering the App under it and modifies status bar style automatically by Operating system itself.

Upvotes: 3

Eric33187
Eric33187

Reputation: 1156

Xcode constantly seems to change this, so this is the latest.

As of 2021 - Swift 5, Xcode 12

To change the status bar to white:

  1. Open your Info.plist.
  2. Add key UIViewControllerBasedStatusBarAppearance and set value to No (false). The human readable version of this is "View controller-based status bar appearance".
  3. Add key UIStatusBarStyle and set value to UIStatusBarStyleLightContent (i.e., "Light Content").

Upvotes: 23

nastassia
nastassia

Reputation: 897

In my case nothing helped. I was trying to change StatusBar color at the ViewController2, that was embded in the NavigationController, which, in turn, was presented modally from ViewController1. This way not worked:

override var preferredStatusBarStyle: UIStatusBarStyle {
    return .darkContent
}

Nothing happened, until I found this solution: Add to ViewController1 this line -

navigationController.modalPresentationCapturesStatusBarAppearance = true

let navigationController = UINavigationController(rootViewController: viewController2)
navigationController.modalPresentationStyle = .overFullScreen
navigationController.modalTransitionStyle = .crossDissolve           
navigationController.modalPresentationCapturesStatusBarAppearance = true
self.present(navigationController, animated: true)

So if you have navigation scheme similar to ViewController1 presented ViewController2, try modalPresentationCapturesStatusBarAppearance property of the presented one

Documentation:

The default value of this property is false.

When you present a view controller by calling the present(_:animated:completion:) method, status bar appearance control is transferred from the presenting to the presented view controller only if the presented controller's modalPresentationStyle value is UIModalPresentationStyle.fullScreen. By setting this property to true, you specify the presented view controller controls status bar appearance, even though presented non-fullscreen.

The system ignores this propertyโ€™s value for a view controller presented fullscreen.

Upvotes: 3

Vivek Sehrawat
Vivek Sehrawat

Reputation: 6570

Simply In App Delegate:

[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];

In Swift 5, Follow the below steps:

  1. Add key UIViewControllerBasedStatusBarAppearance and set value to false in Info.plist
  2. Add key UIStatusBarStyle and set value to UIStatusBarStyleLightContent

Upvotes: 24

Pradeep Mahdevu
Pradeep Mahdevu

Reputation: 7663

Note: The most upvoted answer does not work for iOS 7 / 8

In Info.plist set 'View controller-based status bar appearance' as NO

In AppDelegate add

[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];

to

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
   ...
}    

This solution works for iOS 7 / 8.

Upvotes: 254

heiko
heiko

Reputation: 432

This solution works for apps using the new SwiftUI Lifecycle / iOS 14.0:

I needed to change the status bar text color dynamically and couldn't access window.rootViewController because SceneDelegate doesn't exist for the SwiftUI Lifecycle.

I finally found this easy solution by Xavier Donnellon: https://github.com/xavierdonnellon/swiftui-statusbarstyle

Copy the StatusBarController.swift file into your project and wrap your main view into a RootView:

@main
struct ProjectApp: App {     
    var body: some Scene {
        WindowGroup {
            //wrap main view in RootView
            RootView {
                //Put the view you want your app to present here
                ContentView()
                    //add necessary environment objects here 
            }
        }
    }
}

Then you can change the status bar text color by using the .statusBarStyle(.darkContent) or .statusBarStyle(.lightContent) view modifiers, or by calling e.g. UIApplication.setStatusBarStyle(.lightContent) directly.

Don't forget to set "View controller-based status bar appearance" to "YES" in Info.plist.

Upvotes: 1

Ucdemir
Ucdemir

Reputation: 3098

Here is a better solution extend Navigation controller and put in storyboard

class NVC: UINavigationController {

    override var preferredStatusBarStyle: UIStatusBarStyle {
              return .lightContent
    }

    override func viewDidLoad() {
        super.viewDidLoad()

    self.navigationBar.isHidden = true
    self.navigationController?.navigationBar.isTranslucent = false
      
     self.navigationBar.barTintColor = UIColor.white
     setStatusBarColor(view : self.view)
    }
    

    func setStatusBarColor(view : UIView){
             if #available(iOS 13.0, *) {
                 let app = UIApplication.shared
                 let statusBarHeight: CGFloat = app.statusBarFrame.size.height
                 
                 let statusbarView = UIView()
              statusbarView.backgroundColor = UIColor.black
                 view.addSubview(statusbarView)
               
                 statusbarView.translatesAutoresizingMaskIntoConstraints = false
                 statusbarView.heightAnchor
                     .constraint(equalToConstant: statusBarHeight).isActive = true
                 statusbarView.widthAnchor
                     .constraint(equalTo: view.widthAnchor, multiplier: 1.0).isActive = true
                 statusbarView.topAnchor
                     .constraint(equalTo: view.topAnchor).isActive = true
                 statusbarView.centerXAnchor
                     .constraint(equalTo: view.centerXAnchor).isActive = true
               
             } else {
                 let statusBar = UIApplication.shared.value(forKeyPath: "statusBarWindow.statusBar") as? UIView
              statusBar?.backgroundColor = UIColor.black
             }
         }
}

status bar color will be black and text will be white

Upvotes: 0

Divya Vohra
Divya Vohra

Reputation: 115

extension UIApplication {

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

Upvotes: -2

superm0
superm0

Reputation: 983

In my case for Swift 5, I added these lines:

override func viewDidAppear(_ animated: Bool) {
    navigationController?.navigationBar.barStyle = .black
}

override var preferredStatusBarStyle: UIStatusBarStyle {
    return .lightContent
}

Upvotes: 11

Andrew Kirna
Andrew Kirna

Reputation: 1396

iOS 13 Solution(s)

UINavigationController is a subclass of UIViewController (who knew ๐Ÿ™ƒ)!

Therefore, when presenting view controllers embedded in navigation controllers, you're not really presenting the embedded view controllers; you're presenting the navigation controllers! UINavigationController, as a subclass of UIViewController, inherits preferredStatusBarStyle and childForStatusBarStyle, which you can set as desired.

Any of the following methods should work:

  1. Opt out of Dark Mode entirely
    • In your info.plist, add the following property:
      • Key - UIUserInterfaceStyle (aka. "User Interface Style")
      • Value - Light
  2. Override preferredStatusBarStyle within UINavigationController

    • preferredStatusBarStyle (doc) - The preferred status bar style for the view controller
    • Subclass or extend UINavigationController

      class MyNavigationController: UINavigationController {
          override var preferredStatusBarStyle: UIStatusBarStyle {
              .lightContent
          }
      }
      

      OR

      extension UINavigationController {
          open override var preferredStatusBarStyle: UIStatusBarStyle {
              .lightContent
          }
      }
      
  3. Override childForStatusBarStyle within UINavigationController

    • childForStatusBarStyle (doc) - Called when the system needs the view controller to use for determining status bar style
    • According to Apple's documentation,

      "If your container view controller derives its status bar style from one of its child view controllers, [override this property] and return that child view controller. If you return nil or do not override this method, the status bar style for self is used. If the return value from this method changes, call the setNeedsStatusBarAppearanceUpdate() method."

    • In other words, if you don't implement solution 3 here, the system will fall back to solution 2 above.
    • Subclass or extend UINavigationController

      class MyNavigationController: UINavigationController {
          override var childForStatusBarStyle: UIViewController? {
              topViewController
          }
      }
      

      OR

      extension UINavigationController {    
          open override var childForStatusBarStyle: UIViewController? {
              topViewController
          }
      }
      
    • You can return any view controller you'd like above. I recommend one of the following:

      • topViewController (of UINavigationController) (doc) - The view controller at the top of the navigation stack
      • visibleViewController (of UINavigationController) (doc) - The view controller associated with the currently visible view in the navigation interface (hint: this can include "a view controller that was presented modally on top of the navigation controller itself")

Note: If you decide to subclass UINavigationController, remember to apply that class to your nav controllers through the identity inspector in IB.

P.S. This works on iOS 13 ๐Ÿ˜Ž

Upvotes: 8

Peter B. Kramer
Peter B. Kramer

Reputation: 16563

  1. Set the UIViewControllerBasedStatusBarAppearance to YES in the .plist file.

  2. In the viewDidLoad do a [self setNeedsStatusBarAppearanceUpdate];

  3. Add the following method:

    - (UIStatusBarStyle)preferredStatusBarStyle
    { 
        return UIStatusBarStyleLightContent; 
    }
    

Note: This does not work for controllers inside UINavigationController, please see Tyson's comment below :)

Swift 3 - This will work controllers inside UINavigationController. Add this code inside your controller.

// Preferred status bar style lightContent to use on dark background.
// Swift 3
override var preferredStatusBarStyle: UIStatusBarStyle {
    return .lightContent
}

Swift 5 and SwiftUI

For SwiftUI create a new swift file called HostingController.swift

import Foundation
import UIKit
import SwiftUI

class HostingController: UIHostingController<ContentView> {
    override var preferredStatusBarStyle: UIStatusBarStyle {
        return .lightContent
    }
}

Then change the following lines of code in the SceneDelegate.swift

window.rootViewController = UIHostingController(rootView: ContentView())

to

window.rootViewController = HostingController(rootView: ContentView())

Upvotes: 1478

James Rochabrun
James Rochabrun

Reputation: 4387

Change in info PLIST In Swift 3 is very easy just with 2 steps. Go to your info.plist and change the key View controller-based status bar appearance to "NO". Then in the Appdelegate just add this line in didfinishlaunchingwithoptions method

  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        UIApplication.shared.statusBarStyle = .lightContent
        return true
    }

this has been deprecated in iOS9 now you should do override this property in the rootviewcontroller

doing this has been deprecated in iOS 9 should do this on the rootviewcontroller

override var preferredStatusBarStyle: UIStatusBarStyle {
        return .lightContent
 }

Upvotes: 25

Krunal
Krunal

Reputation: 79746

Here is Apple Guidelines/Instruction about status bar change. Only Dark & light (while & black) are allowed in status bar.

Here is - How to change status bar style:

If you want to set status bar style, application level then set UIViewControllerBasedStatusBarAppearance to NO in your `.plist' file.

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.

-

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


Here is some hacky trick to change/set background color for status bar during application launch or during viewDidLoad of your view controller.

extension UIApplication {

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

}

// Set upon application launch, if you've application based status bar
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        UIApplication.shared.statusBarView?.backgroundColor = UIColor.red
        return true
    }
}


or 
// Set it from your view controller if you've view controller based statusbar
class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        UIApplication.shared.statusBarView?.backgroundColor = UIColor.red
    }

}



Here is result:

enter image description here

Upvotes: 13

Karthick C
Karthick C

Reputation: 1529

Please try this

[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
    [application setStatusBarHidden:NO];
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
    UIView *statusBar = [[[UIApplication sharedApplication] valueForKey:@"statusBarWindow"] valueForKey:@"statusBar"];
    if ([statusBar respondsToSelector:@selector(setBackgroundColor:)]) {
        statusBar.backgroundColor = [UIColor blackColor];
    }

Upvotes: 1

Datt Patel
Datt Patel

Reputation: 1213

change the status bar text color for all ViewControllers

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
     }
 }

objective c

create category class

For UIViewController

In UIViewController+StatusBarStyle.h

 @interface UIViewController (StatusBarStyle)
 @end

In UIViewController+StatusBarStyle.m

 #import "UIViewController+StatusBarStyle.h"

 @implementation UIViewController (StatusBarStyle)
 -(UIStatusBarStyle)preferredStatusBarStyle
 {
  return UIStatusBarStyleLightContent;
 }
 @end 

For UINavigationController

In UINavigationController+StatusBarStyle.h

 @interface UINavigationController (StatusBarStyle)
 @end

In UINavigationController+StatusBarStyle.m

 #import "UINavigationController+StatusBarStyle.h"

 @implementation UINavigationController (StatusBarStyle)
 -(UIStatusBarStyle)preferredStatusBarStyle
 {
  return UIStatusBarStyleLightContent;
 }
 @end  

Upvotes: 4

S. Matsepura
S. Matsepura

Reputation: 1693

In iOS 8: add NavigationController.NavigationBar.BarStyle = UIBarStyle.Black; to viewDidLoad

Upvotes: 4

Khurshid
Khurshid

Reputation: 117

Very Easy way To change the status bar color. Create the subclass of navigation Controller.

Write this code in view didload method. Effect this code in all view controller

self.navigationBar.titleTextAttributes = @{NSForegroundColorAttributeName :
                                                                        [UIColor whiteColor],
                                               NSFontAttributeName:[UIFont boldSystemFontOfSize:19]};

Upvotes: -4

Cmar
Cmar

Reputation: 141

What I had to do for swift and navigation controller

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

Upvotes: 1

Zaid Pathan
Zaid Pathan

Reputation: 16820

Swift 3 - Xcode 8.

If you want status bar to initially hidden on Launch screen then try this,

Step 1: Add following to info.plist.

  • View controller-based status bar appearance value NO
  • Status bar is initially hidden value YES

Step 2: Write this in didFinishLaunchingWithOptions method.

UIApplication.shared.isStatusBarHidden = false
UIApplication.shared.statusBarStyle = UIStatusBarStyle.lightContent

Upvotes: 6

Lucas
Lucas

Reputation: 6729

You can do this without writing any line of code!
Do the following to make the status bar text color white through the whole app

On you project plist file:

  • Status bar style: Transparent black style (alpha of 0.5)
  • View controller-based status bar appearance: NO
  • Status bar is initially hidden: NO

Upvotes: 459

Wanbok Choi
Wanbok Choi

Reputation: 5452

  1. Go to Project -> Target,

  2. Then set Status Bar Style to Light. It makes status-bar white from the launch screen. Project Setting

  3. Then set View controller-based status bar appearance equal to NO in Info.plist.

Upvotes: 28

Mahendra Liya
Mahendra Liya

Reputation: 13218

The easiest way to do this from Xcode (without any coding) is:

  • Add View controller-based status bar appearance to your Info.plist and set the value to NO.
  • Now, go to your project target and inside Deployment Info you'll find an option for Status Bar Style. Set the value of this option to Light.

You'll have the White status bar.

Upvotes: 3

IOS developer
IOS developer

Reputation: 47

Just Change in 1) Info.plist View controller-based status bar appearance -> NO and write 2)

  [[UIApplication
 sharedApplication]setStatusBarStyle:UIStatusBarStyleLightContent]; 

in

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

Upvotes: 2

Ajinkya Patil
Ajinkya Patil

Reputation: 5548

You dont need to do any code for this

You need to add "View controller-based status bar appearance" key in info.plist as follows: enter image description here

& set its value type to Boolean & value to NO. Then click on project settings,then click on General Tab & under Deployment Info set the preferred status bar style to .Light as follows:

enter image description here

Thats it.

Upvotes: 84

eirik
eirik

Reputation: 407

If you still want to use View controller-based status bar appearance in info.plist set to YES, meaning that you can change the statusbar for each view-controller, use the following for white text in the status-bar in ViewDidLoad:

[[[self navigationController] navigationBar] setBarStyle:UIBarStyleBlackTranslucent];

Upvotes: 9

fraxool
fraxool

Reputation: 3229

If you want the same result with Swift, you can use this code in your AppDelegate.swift file :

UINavigationBar.appearance().barStyle = .BlackTranslucent

And the text of your status bar will be white :-) !

Upvotes: 9

haraldmartin
haraldmartin

Reputation: 1592

For me, nothing happened with using all the things in the other answers (and from other sources/documentation). What did help was to set the Navigation Bar Style to "Black" in the XIB. This changed the text to white without any code at all.

Enter image description here

Upvotes: 126

Konstantine Kalbazov
Konstantine Kalbazov

Reputation: 2673

If your application needs to have UIStatusBarStyleLightContent by default, but you still want to have the ability to use UIStatusBarStyleDefault on some screens, you could choose to manage the status bar color on the controller level, but in this case you'll have to overwrite preferredStatusBarStyle in every view controller (or implement it in a base view controller, from which all your other view controllers will inherit). Here's another way of solving this problem:

  • Set the UIViewControllerBasedStatusBarAppearance to NO in the plist
  • Set the UIStatusBarStyle to UIStatusBarStyleLightContent

All view controllers will use white text for the status bar. Now add this methods only in the view controllers that need the status bar with black text:

-(void)viewWillAppear:(BOOL)animated  
{  
  [super viewWillAppear:animated];  
  [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault];
}    

-(void)viewWillDisappear:(BOOL)animated  
{  
  [super viewWillAppear:animated];  
  [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
}    

Upvotes: 3

Related Questions