Reputation: 7067
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?
Upvotes: 235
Views: 315381
Reputation: 553
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 {
.lightContent
}
Upvotes: 3
Reputation: 4010
(As of October 25, 2021)
Swift 5, Swift 4.2, Swift 4
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
setNeedsStatusBarAppearanceUpdate()
}
override var preferredStatusBarStyle: UIStatusBarStyle {
.lightContent
}
Upvotes: 164
Reputation: 1333
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:
Upvotes: 0
Reputation: 61
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
Upvotes: 6
Reputation: 14417
(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
}
}
Upvotes: 15
Reputation: 1529
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
}
}
Upvotes: -3
Reputation: 1818
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)
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
}
}
Upvotes: 2
Reputation: 83
if somebody wants to change the battery and text color of the status bar like the below image:
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]
Upvotes: -4
Reputation: 688
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
}
Upvotes: 2
Reputation: 8167
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
Upvotes: 6
Reputation: 381
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
}
}
Upvotes: 8
Reputation: 31
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
Upvotes: 1
Reputation: 989
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)
Upvotes: 1
Reputation: 21
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
Upvotes: 2
Reputation: 531
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
}
Upvotes: 52
Reputation: 5648
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...
Upvotes: 1
Reputation: 269
Swift 4 For specific ViewController without navigationViewController embedded just add this to your ViewController file.
override var preferredStatusBarStyle : UIStatusBarStyle {
return .lightContent
}
Upvotes: 7
Reputation: 1051
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
UIViewControllerBasedStatusBarAppearance
to false
.AppDelegate.swift
, which contains didFinishLaunchingWithOptions
, set the color you want.UIApplication.sharedApplication().statusBarStyle = UIStatusBarStyle.LightContent
Swift 3 Update *
UIApplication.shared.statusBarStyle = .lightContent
Upvotes: 32
Reputation: 2290
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!
Upvotes: 3
Reputation: 601
Swift 3
In your AppDelegate
file inside func application
method
let statusBar: UIView = application.value(forKey: "statusBar") as! UIView
statusBar.backgroundColor = .red
Upvotes: -2
Reputation: 3655
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
}
Upvotes: 9
Reputation: 7067
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
Upvotes: 366
Reputation: 451
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:
info.plist
to YES.preferredStatusBarStyle
.modalPresentationCapturesStatusBarAppearance
to Yes that is.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 childViewControllerForStatusBarStyle
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
}
Upvotes: 5
Reputation: 4192
There's a billion answers here so I thought why not add another in the form of an extension (with help from @Cœur)
extension UIApplication {
class var statusBarBackgroundColor: UIColor? {
get {
return (shared.value(forKey: "statusBar") as? UIView)?.backgroundColor
} set {
(shared.value(forKey: "statusBar") as? UIView)?.backgroundColor = newValue
}
}
}
UIApplication.statusBarBackgroundColor = .blue
Upvotes: 21
Reputation: 556
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
}
}
Upvotes: 9
Reputation: 21
Swift 3.0 Update
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
UIApplication.shared.statusBarStyle = .lightContent
return true
}
Upvotes: 2
Reputation: 600
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.
Upvotes: 15
Reputation: 213
I can suggest you a simpler way,
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.
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 :)
Upvotes: 4
Reputation: 197
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)
Upvotes: 9
Reputation: 36447
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
Upvotes: 4