Change Status Bar Background Color in Swift 3

85,901

Solution 1

extension UIApplication {
    var statusBarView: UIView? {
        if responds(to: Selector(("statusBar"))) {
            return value(forKey: "statusBar") as? UIView
        }
        return nil
    }
}

UIApplication.shared.statusBarView?.backgroundColor = .red

Update for iOS 13

App called -statusBar or -statusBarWindow on UIApplication: this code must be changed as there's no longer a status bar or status bar window. Use the statusBarManager object on the window scene instead.

Refer to How to change the status bar background color and text color on iOS 13?

Solution 2

"Change" status bar background color:

let statusBarView = UIView(frame: UIApplication.shared.statusBarFrame)
let statusBarColor = UIColor(red: 32/255, green: 149/255, blue: 215/255, alpha: 1.0)
statusBarView.backgroundColor = statusBarColor
view.addSubview(statusBarView)

Change status bar text color:

override var preferredStatusBarStyle: UIStatusBarStyle {
    return .lightContent
}

Update: please note that the status bar frame will change when the view is rotated. You could update the created subview frame by:

  • Using the autoresizing mask: statusBarView.autoresizingMask = [.flexibleWidth, .flexibleTopMargin]
  • Observing NSNotification.Name.UIApplicationWillChangeStatusBarOrientation
  • Or overriding viewWillLayoutSubviews()

Solution 3

With using Swift 3 and 4 you can use the code snippet on below. It finds the view from UIApplication using valueForKeyPath as set it's background color.

guard let statusBarView = UIApplication.shared.value(forKeyPath: "statusBarWindow.statusBar") as? UIView else {
        return
    }
statusBarView.backgroundColor = UIColor.red

Objective-C

UIView *statusBarView = [UIApplication.sharedApplication valueForKeyPath:@"statusBarWindow.statusBar"];
if (statusBarView != nil)
{
    statusBarView.backgroundColor = [UIColor redColor];
}

Solution 4

For Xcode 9 and iOS 11: The style of the status bar we will try to achieve is a status bar with white content. Go to the ViewController.swift file and add the following lines of code.

override var preferredStatusBarStyle: UIStatusBarStyle {

     return .lightContent

}

Or from project settings option you can change status bar's style:

enter image description here

Next, go back to the Storyboard, Select the View Controller and in the Editor menu Select Embed in Navigation Controller. Select the Navigation Bar and in the Attribute Inspector set the Bar Tint color to red. The Storyboard will look like this. enter image description here

Build and Run the project, The content of the status bar is dark again, which is the default. The reason for this is, iOS asked for the style of the status bar of the navigation controller instead of the contained view controller.

enter image description here

To change the style of all navigation controller inside the app, change the following method in the AppDelegate.swift file.

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

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

Build and Run the Project again, this time the content of the status bar changed to white.

enter image description here

Solution 5

I have a custom solution for changing status bar on iOS 13 and below. Here is how to do that:

if #available(iOS 13.0, *) {
   let app = UIApplication.shared
   let statusBarHeight: CGFloat = app.statusBarFrame.size.height

   let statusbarView = UIView()
   statusbarView.backgroundColor = UIColor.red
   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.red
}

Gist

Also, check the article iOS 13 How to Change StatusBar Color?

One last thing, you can still change statusbar style with :

 override var preferredStatusBarStyle : UIStatusBarStyle {
    return UIStatusBarStyle.lightContent
    //return UIStatusBarStyle.default   // Make dark again
}
Share:
85,901
derdida
Author by

derdida

Software Developer with Experience in PHP, Swift, Objective C, Javascript, C#.

Updated on July 05, 2022

Comments

  • derdida
    derdida almost 2 years

    In XCode 7.3.x ill changed the background Color for my StatusBar with:

    func setStatusBarBackgroundColor(color: UIColor) {
    guard  let statusBar = UIApplication.sharedApplication().valueForKey("statusBarWindow")?.valueForKey("statusBar") as? UIView else {
        return
    }
    statusBar.backgroundColor = color
    }
    

    But it seems that this is not working anymore with Swift 3.0.

    Ill tried with:

    func setStatusBarBackgroundColor(color: UIColor) {
    guard  let statusBar = (UIApplication.shared.value(forKey: "statusBarWindow") as AnyObject).value(forKey: "statusBar") as? UIView else {
        return
    }
    statusBar.backgroundColor = color
    }
    

    But it gives me:

    this class is not key value coding-compliant for the key statusBar.
    

    Any Ideas how to change it with XCode8/Swift 3.0?

  • derdida
    derdida over 7 years
    Statusbar, not NavigationBar.
  • iGranDav
    iGranDav over 7 years
    This isn't a good practice at all, I highly discourage to use this method since this UIView is private. I am curious to see if your app gets approved using this.
  • breaktop
    breaktop over 7 years
    @iGranDav Why isn't this good practice. The method value(forKey key: String) is open so I'm assuming its ok to use. Can you please explain. If this is bad practice, how would you change the background color or the status bar. This methd has worked for me. I've tried adding a subview to the window object in the AppDelegate and that didn't work.
  • iGranDav
    iGranDav over 7 years
    @breaktop using the value(forKey key: String) method you are using the KVC of objc runtime to access a view you shouldn't have access to (and has no documentation referring to it BTW) during runtime only. This construction is used under iOS 10 but not under iOS 9 for instance (where you need to access the statusBarWindow first), and you have absolutely no clue that it will persists under iOS 11. Internal construction and no docs means that Apple does not have any contract to respect here.
  • Sanket_B
    Sanket_B about 6 years
    Did anyone face app rejection by using this code? or it is safe to use?
  • Callam
    Callam about 6 years
    @SanketBhavsar I have not faced a rejection for using it as of yet
  • fahrulazmi
    fahrulazmi about 6 years
    I have problem with this method on iPhone X. The background color becomes transparent when app switcher (home indicator) gesture is activated.
  • Surendra Kumar
    Surendra Kumar almost 5 years
    Its is not working properly with iPhone X devices . It cover only half of status bar.
  • Jamil Hasnine Tamim
    Jamil Hasnine Tamim almost 5 years
    <3 @Satnam Sync
  • hong developer
    hong developer over 4 years
    keyWindow is deprecated in iOS 13.
  • Jainil Patel
    Jainil Patel over 4 years
    UIApplication.shared.statusBarUIView?.backgroundColor = .white
  • Jainil Patel
    Jainil Patel over 4 years
    UIApplication.shared.statusBarUIView?.backgroundColor = .white
  • Dani
    Dani over 3 years
    @JainilPatel invalid
  • Faizyy
    Faizyy over 3 years
    Doesn't work on xcode12. App crashes with, Thread 1: "App called -statusBar or -statusBarWindow on UIApplication: this code must be changed as there's no longer a status bar or status bar window. Use the statusBarManager object on the window scene instead."
  • Alessandro Ornano
    Alessandro Ornano about 3 years
    This one crash in Swift 5
  • Alessandro Ornano
    Alessandro Ornano about 3 years
    what is statusBarView?
  • Sentry.co
    Sentry.co over 2 years
    Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'App called -statusBar or -statusBarWindow on UIApplication: this code must be changed as there's no longer a status bar or status bar window. Use the statusBarManager object on the window scene instead.'
  • Sentry.co
    Sentry.co over 2 years
    'keyWindow' was deprecated in iOS 13.0: Should not be used for applications that support multiple scenes as it returns a key window across all connected scenes
  • Krunal
    Krunal over 2 years
    @Sentry.co - I tested and posted this answer 3 years back. You are welcomed to update this answer and improve its quality to make it aligned with latest technological changes in Swift/iOS.
  • Sentry.co
    Sentry.co over 2 years
    Yepp. My comment is intended to warn people that are trying to solve this too look else where as it wont work anymore. I got it working now but it requires a lot of research as no-one has it worked out on StackOverflow yet. Here is the solution that is working for iOS 15. (its not elegant at all) gist.github.com/eonist/ffc0788c57d620aac43ae15cec4b00a9
  • Jainil Patel
    Jainil Patel over 2 years
    When i wrote the answer i was learning shift language. So it is too old answer.
  • Sentry.co
    Sentry.co over 2 years
    no worries. Just letting future internet dwellers know that iOS has changed how this works. Currently I'm using this solution: gist.github.com/eonist/ffc0788c57d620aac43ae15cec4b00a9
  • Nativ
    Nativ over 2 years
    Underrated solution. Thumbs up