Status Bar Style issues since Xcode 11.4 - ios

Since Xcode 11.4 overriding the preferredStatusBarStyle property does not seem to work anymore in some cases.
We have an extension of UINavigationController where we override it for basically every ViewController but this property is no longer called since Xcode 11.4. Therefore the status bar is black for mostly all ViewControllers.
extension UINavigationController {
override open var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
}
It also stopped working for some ViewControllers where we override preferredStatusBarStyle again. The property gets accessed, however, the status bar does not change its color.
View controller-based status bar appearance is set to YES in info.plist.
Issue occurs on simulator and real devices.
Does anyone have this problem too?

Ok I found a solution. Looks like I need to set the barStyle of the navigationBar to .black as described here
navigationController?.navigationBar.barStyle = .black
Not sure though why this is necessary now.
The UINavigationController extension is no longer needed then.

change the UIStatusBarStyle in appdelegates in this:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
return true
}

Related

preferredStatusBarStyle .lightContent doesn't work with Navigation Controller

preferredStatusBarStyle .lightContent doesn't work with Navigation Controller. I have tried this method below
override var preferredStatusBarStyle: UIStatusBarStyle { return .lightContent }
This is my first time to face this kind of issue. This code works in my Previous apps.
I even change this in my target:
I think you forget to change statusbar style in info.plist
Change in info.plist the row
View controller-based status bar appearance and set it to YES
and in Your ViewController:
override var preferredStatusBarStyle: UIStatusBarStyle { return .lightContent }
No other code is required
Make sure that in your Info.plist file you have View controller-based status bar appearance set to NO. It would also be helpful to check that you don't programatically set the status bar to a different color in a view controller by accident. If you're using the above function, do you call self.setNeedsStatusBarAppearanceUpdate? But you shouldn't need to write any code at all if you set Light as the value in your project settings and NO in your plist file.
Another option that has worked for me in the past is in your AppDelegate file, in the didFinishLaunchingWithOptions function do this:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
UIApplication.shared.statusBarStyle = .lightContent
return true
}

Is it possible to change Status Bar color for all view controllers?

I have been searching for a while now and I only found answers that describe to change color on one view controller not for all view controllers.
Is it possible to do it?
Only two steps are needed to change the status bar style for the entire app. 🙂
Step 1
Add a new property to the project's Info.plist file and set it to false.
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
Step 2
Go to your project's target and under General / Deployment Info, switch Status Bar Style from Default to Light.
Doing these steps will ensure the status bar behaves the same in the entire project.
Set the style of the status bar in AppDelegate.swift:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
UIApplication.shared.statusBarStyle = .lightContent
return true
}
And add the following code to your Info.plist:
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
First in info.plist set View controller-based status bar appearance to NO
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
let statusBar: UIView = UIApplication.shared.value(forKey: "statusBar") as! UIView
if statusBar.responds(to:#selector(setter: UIView.backgroundColor)) {
statusBar.backgroundColor = UIColor.blue
}
UIApplication.shared.statusBarStyle = .lightContent
return true
}
The output screenshot is below
You can 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:
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.
Or programatically you can do it from app delegate:
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:
Set the UIViewControllerBasedStatusBarAppearance to YES in the .plist file, if you need to set status bar style at UIViewController level only.
In the viewDidLoad add function - setNeedsStatusBarAppearanceUpdate
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.
Swift 4
In AppDelegate.swift add this extension:
extension UINavigationController {
override open var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
}
Yes,
Step 1:
Open your info.plist and insert a new key named "View controller-based status bar appearance" to NO
Step 2:
Open the viewcontroller file where you want to change the statusBarStyle and put the following code in viewWillAppear(),
UIApplication.shared.statusBarStyle = .lightContent
Step 3 :
Also, implement the viewWillDisappear() method for that specific viewController and put the following lines of code,
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
UIApplication.shared.statusBarStyle = UIStatusBarStyle.default
}
All the best
Important clarification
It is very important to understand two approaches to customizing the status bar.
Is it possible to change Status Bar color for all view controllers?
Boolean answer is Yes, but, in legal way, it is so close to No that answering Yes is provocative if you need colors other that black or white.
There are two approaches when it comes to customizing Status bar appearance.
First approach – one color for whole app
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. This is what you needed. But. You are limited to only two settings: white and black. And there's no way you can customize it using documented API.
To set this up:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
application.statusBarStyle = .lightContent
return true
}
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
}
You have the same as in first, set either dark or light style for statusbar.
Third approach – Hack!
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
if let statusbar = value(forKey: "statusBar") as? UIView {
statusbar.backgroundColor = UIColor.blue
}
return true
}
Why hack? If you need status bar color other than black or white. Here you use undocumented API. You get statusBar object using KVC and manually set its color. This is dirty, not legal way, but so far it's the only way to set up custom color for statusbar. It may well lead your app to being rejected. But maybe you're lucky. In order to set it once and for all, you will need to set to NO the aforementioned flag so that status bar did not initialize its style with each view controller.

Set color of text in status bar it is not working (swift 3 - iOS 10)

My status bar is black and I'm trying to set as white, so I did what I found in some questions here and put this on my AppDelegate...
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
//Status bar color
UIApplication.shared.statusBarStyle = .lightContent
return true
}
There is no error in my console, nothing about this. The status bar text is still black. What could be causing this? There is another way to do that in swift 3.0?
ensure once in your project info.plist the row
View controller-based status bar appearance and set it to NO
In Swift3 you have to use following code, put anywhere in your view controller
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
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:
Set the UIViewControllerBasedStatusBarAppearance to YES in the .plist file, if you need to set status bar style at UIViewController level only.
In the viewDidLoad add function - setNeedsStatusBarAppearanceUpdate
override preferredStatusBarStyle in your view controller.
-
override func viewDidLoad() {
super.viewDidLoad()
self.setNeedsStatusBarAppearanceUpdate()
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}

how do I properly change my status bar style in swift 2/ iOS 9?

I'm attempting to change my status bar's style to .Light but the previous code I implemented in swift 1.2 seems not to work anymore.. here's the code:
override func viewDidLoad() {
super.viewDidLoad()
UIApplication.sharedApplication().statusBarStyle = .LightContent
}
now I have my View controller-based status bar appearance info.plist setting to YES, and reading the UIKit doc, this will negate any statusBarStyle changes and keep it at default. However when I change the setting to 'NO' and change the statusBarStyle, I get this <Error>: CGContextSaveGState: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable in my debugger.. So is this a bug in Xcode? because to change the status bar style you must change info.plist setting to NO, but when that happens.. error
Apple have added the capability to change the status bar style in the deployment info. Simply choose 'Light'.
Also set View controller-based status bar appearance key to NO in the Info.plist
I always did this way.
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
//Changing Status Bar
override func preferredStatusBarStyle() -> UIStatusBarStyle {
//LightContent
return UIStatusBarStyle.LightContent
//Default
//return UIStatusBarStyle.Default
}
}
It works in any swift 2.x version. This requires that you set View controller-based status bar appearance in your Info.plist file to YES.
Swift 3 just add View controller-based status bar appearance with value NO to info.plistand then add to ViewControllerwhere you want:
UIApplication.shared.statusBarStyle = UIStatusBarStyle.lightContent
You can still use preferredStatusBarStyle in your view controller:
step 1: in the info.plist set ViewControllerBasedStatusBarAppearance to YES.
step 2: add this code to the ViewController you'd like to edit :
override func preferredStatusBarStyle() -> UIStatusBarStyle {
return UIStatusBarStyle.LightContent
}
*** Tip: It seems to only work outside of the ViewDidLoad(), didReceiveMemoryWarning() functions.
The change in deployment info works but despite - you need to add the
'View controller-based status bar appearance' key to plist file setting it to NO.
You can also just add this in the AppDelegate. This option is better if you want to change it for every ViewController in the app and not have to make it different for every other VC.
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
application.statusBarStyle = UIStatusBarStyle.LightContent
// instead of
// UIApplication.sharedApplication().setStatusBarStyle(UIStatusBarStyle.LightContent, animated: false)
// which gives warning about deprecation in iOS 9
return true
}
It looks like it's a bug in Xcode 7.0. I'm also getting the Error>: CGContextSaveGState: invalid context 0x0. error when setting View controller-based status bar appearance
For now I'm just overriding the status bar color in every view controller.
override func preferredStatusBarStyle() -> UIStatusBarStyle {
return .LightContent
}
You can choose "light" in the deployment info, but then you also need to add the "View controller-based status bar appearance" and set it to NO.
Here try this it might help you
First goto info.plist file and add this "View controller-based status bar appearance" as a key and set the value as NO
here below shown in the image
after this come to AppDelegate.swift file and past this UIApplication.sharedApplication().statusBarStyle = UIStatusBarStyle.LightContent line of code in
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool{
UIApplication.sharedApplication().statusBarStyle = UIStatusBarStyle.LightContent
return true
}
like this
For swift 3 override the preferredStatusBarStyle variable use this:
override var preferredStatusBarStyle: UIStatusBarStyle{
return .lightContent
}
The existing answers are great, but it's a little different now with the new updates!
override var now instead of override func for anyone confused - the gist is still the same and you still need to change your 'Info.plist':
override var preferredStatusBarStyle: UIStatusBarStyle
{
//LightContent
return UIStatusBarStyle.lightContent
//Default
//return UIStatusBarStyle.default
}
If you want to change it from time to time inside your app, you can use the overrides preferredStatusBarStyle() as mentioned before.
Just make sure, that you also call setNeedsStatusBarAppearanceUpdate() after calling preferredStatusBarStyle(), to inform IOS about it.

Swift UIApplication.setStatusBarStyle Doesn't work

Here's my implementation in a subclass of UIViewController:
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
UIApplication.sharedApplication().setStatusBarStyle(UIStatusBarStyle.LightContent, animated: false)
}
I tried putting it in AppDelegate initialisation code (using the passed in UIApplication instance), however the status bar is still black..
Is this a bug with iOS 8 or am I doing it wrong?
Note: I may be breaking someone's law's here by discussing ios 8.. Its a general problem that, when compiled doesn't work for ios 7 either.
Update: Still doesn't work, even with value in Info.plist and code in - didFinishLaunchingWithOptions
You really should implement preferredStatusBarStyle on your view controller(s):
override func preferredStatusBarStyle() -> UIStatusBarStyle {
return .LightContent
}
Go to Info.plist file
Hover on one of those lines and a (+) and (-)
button will show up.
Click the plus button to add new key Type in
start with capital V and automatically the first choice will be View
controller-based status bar appearance.
Add that as the KEY.
Set the VALUE to "NO"
Go to you AppDelegate.swift
Add the following code, inside the method
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject:AnyObject]?) -> Bool {
application.setStatusBarStyle(UIStatusBarStyle.LightContent, animated: false)
return true
}
DONE! Run your app and your status bar is now WHITE!

Resources