iOS 13 Status Bar Glitch - ios

There seems to be a glitch on iOS 13 when trying to change the status bar color from one view controller to the other. The previous view controller overrides the preferred status bar style to light content. When navigating to a child view, I call the following code to set the status bar based on the interface style.
override var preferredStatusBarStyle: UIStatusBarStyle {
if #available(iOS 13, *) {
if self.traitCollection.userInterfaceStyle == .dark {
return .darkContent
} else {
return .lightContent
}
}
return .default
}
The status bar looks like so, where half of it is light and the time is dark (as it should be). After an arbitrary amount of time the status bar will draw properly. Ive tried calling setNeedsStatusBarDisplay(). Which does get called but does not fix the problem after a re-render.
This only happens on iOS 13. Tested across multiple devices
Status bar glitch. Time is light where as battery and network icons are dark:
Thanks in advance!

Here is what I do to fix this issue:
#interface AHTabBarController : UITabBarController
- (UIViewController *)childViewControllerForStatusBarStyle {
UINavigationController *navigationController = self.selectedViewController;
navigationController.navigationBar.barStyle = UIBarStyleDefault; // status bar style
return navigationController;
}

I got the same status bar glitch every time when I was changing UIWindow.rootViewController. It was reproducible even in empty project, created from scratch in Xcode 11 and already configured correctly by it. But on iOS 12 and below everything works fine.
I've found the solution for iOS 13 that works for me. If you update your project from Xcode 10 / iOS 12, you should add SceneDelegate to the project first (I've done it according to this manual). Then, right after changing root view controller you should call makeKeyAndVisible:
if (#available(iOS 13, *)) {
id<UIWindowSceneDelegate> sceneDelegate = (id<UIWindowSceneDelegate>) UIApplication.sharedApplication.connectedScenes.allObjects.firstObject.delegate;
[sceneDelegate.window makeKeyAndVisible];
}
Sorry for Objective-C code, but Swift version is pretty similar.

this isn't a glitch this set it back to Default
override var preferredStatusBarStyle: UIStatusBarStyle {
return self.style
}
var style: UIStatusBarStyle = .default

Fixed it by setting the View controller-based status bar appearance in the info.plist to NO.
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>

Related

Style status bar when navigation bar is hidden

I know that with UIKit usually you just override:
override var preferredStatusBarStyle: UIStatusBarStyle { return .lightContent }
in your UIViewController (or UINavigationController if it exists). It works perfectly fine.
However, I run into a problem when I perform this:
navigationController?.setNavigationBarHidden(true, animated: true)
Now, I can see no navigation bar, which is expected and perfectly fine. However, I see the status bar with the dark font, what is unexpected (my navigation controller overrides above property and it works properly when the navigation bar is not hidden). I want to see the status bar, but I want it in a light font. Navigation controller from this point does not listen to preferredStatusBarStyle, so I can't set it up this way.
Is there any way to display .lightContent status bar style when the navigation bar is hidden..?
The end effect is visible on the screenshot. If you zoom in, you can see dark letters & battery on dark background.
PS. Please do not post answers only about SwiftUI (here we support old iOS as well) & deprecated stuff.
Found a solution to make SDK ask for style when there is a navigation controller and the navigation bar is hidden but the status bar is shown.
In UINavigationController subclass, you need to override
override var childForStatusBarStyle: UIViewController? { return viewControllers.last }
And then inside these controllers, you can specify
override var preferredStatusBarStyle: UIStatusBarStyle { return .lightContent }
For some reason, if the navigation bar is hidden, iOS SDK does not ask navigation controller for preferredStatusBarStyle. However, it still asks childForStatusBarStyle and we've got an issue fixed :)
Try to set your status bar style to light
After that set View controller-based status bar appearance to NO in your info.plist
UPDATE
If you want the light content only in one view you can try to override the user interface style to dark in viewDidLoad
if #available(iOS 13.0, *) {
self.overrideUserInterfaceStyle = .dark
}

iOS 11 UINavigationBar Transparency in pushed ViewController

I've been trying to implement Apple Music like transparent navigation bar for pushed view controller. There are a lot of solutions on Internet saying place the code below into viewDidLoad:
navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
navigationController?.navigationBar.shadowImage = UIImage()
But the thing is that it only works for root controller, e.g. UITableViewController with a list of items. When I tap on an item and open it's details I expect to see transparent navigation bar, but after appearing it becomes solid (not even translucent). Even setting barTintColor does not help.
What am i doing wrong? Or is it a known issue in iOS 11? It used to work before...
I confirm that transparent navigation bar is not working in iOS 11 for pushed viewcontroller, instead just appears black without translucent #screenshot.
Firstly, I have filed this bug report, lastly :) I found a quick workaround that presenting and dismissing a UIViewcontroller fixes this issue, as following:
if (self.navigationController!.viewControllers.count > 1) {
if #available(iOS 11.0, *) {
self.present(UIViewController(), animated: true, completion: {
self.dismiss(animated: false)
})
self.scrollView.contentInsetAdjustmentBehavior = .never
} else {
self.automaticallyAdjustsScrollViewInsets = false
}
self.extendedLayoutIncludesOpaqueBars = false
}
I am using above code in viewWillAppear and my UI is being generated programatically without storyboard or xib, so it works seamlessly :) and glad I get expected result #screenshot

Cannot set iOS Status Bar Colour for View

I am developing an app for iOS8, using Swift 1.2.
However, I am having an issue with the colour of the status bar (the one with the time, battery indicator etc).
In my Info.plist file, I have UIViewControllerBasedStatusBarAppearance set to YES as well as Status bar style set to UIStatusBarStyleLightContent and then in all my view controllers in the Storyboard, I have the status bar set to "Light Content".
This works for all of my NavigationViewControllers and views embedded within NavigationViewControllers, however I have one normal TableViewController which is not embedded in a NavigationController, and when I push this view modally, the status bar changes to BLACK!???
Even when I look at the view in the Storyboard editor it shows as a white status bar (note the faint white battery indicator at the right of the below screenshot):
But when I build and run on my iPhone, the status bar shows as black...
Why is this? How can I fix this? I don't know what could be incorrect.
Please make sure to add View controller-based status bar appearance (UIViewControllerBasedStatusBarAppearance) with value NO to your Info.plist
UPDATE:
I found the solution to this was very easy, from another StackOverflow article (Swift UIApplication.setStatusBarStyle Doesn't work).
For anyone else wanting to set the status bar colour programmatically, I just inserted the following code into my ViewController for the view in question:
- Swift 4.0+
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
- Earlier Swifts (4.0-)
override func preferredStatusBarStyle() -> UIStatusBarStyle {
return .LightContent
}
These are setups for UIStatusBar style:
Go to AppDelegate.swift in that add below code line in didFinishLaunchingWithOptions method:
UIApplication.sharedApplication().statusBarStyle = UIStatusBarStyle.LightContent
Add below keys into .plist file.
In Storyboard select your controller UINavigationController or UIViewController. And set status bar style as Light Content
For Swift 3
in your AppDelegate.swift file in function didFinishLaunchingWithOptions
UIApplication.shared.statusBarStyle = UIStatusBarStyle.lightContent
add this Line in your Appdelegate.swift file :
UIApplication.sharedApplication().statusBarStyle = .LightContent

iOS 8 light status bar not working

I've set the background color of the main UIView in my view controller to a bluish color.
I've also tried all combinations of the following:
Adding this to the app delegate:
UIApplication.sharedApplication().setStatusBarStyle(UIStatusBarStyle.LightContent, animated: true)
Setting View controller status based application to NO and YES
Setting 'Status Bar Style' to Light in the project overview.
I'm seeing black status bar text when I want to see white text.
I'd like to set the style at the application level, not the VC level.
My info.plist:
for all IOS 9+
In your plist file change add/change your table with these 2 lines.
1) View controller-based status bar appearance to NO
2) Status bar style to UIStatusBarStyleLightContent
If you want to change style in running app for any reason use this
[UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent;
this saved my life numerous times! :-)
Status bar style is determined (by default) at the level of the view controller, not the application. Implement preferredStatusBarStyle in your view controller.
class ViewController : UIViewController {
override func preferredStatusBarStyle() -> UIStatusBarStyle {
return .LightContent
}
}
You can determine status bar style at the application level, but to do so, you must throw a switch in your Info.plist. See the docs:
To opt out of the view controller-based status bar appearance behavior, you must add the UIViewControllerBasedStatusBarAppearance key with a value of NO to your app’s Info.plist file, but doing so is not recommended [my italics, and I don't even know whether this is even supported any longer].
Swift 4
In Info.plist add this property
View controller-based status bar appearance to NO
and after that in AppDelegate inside the didFinishLaunchingWithOptions add these code
UIApplication.shared.isStatusBarHidden = false
UIApplication.shared.statusBarStyle = .lightContent
you can use this code
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
might be Solve this issue.

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?
Set the UIViewControllerBasedStatusBarAppearance to YES in the .plist file.
In the viewDidLoad do a [self setNeedsStatusBarAppearanceUpdate];
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())
Alternatively, you can opt out of the view-controller based status bar appearance:
Set View controller-based status bar appearance to NO in your Info.plist.
Call [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
Note: This method has been deprecated in iOS9. Use preferredStatusBarStyle on the UIViewController instead. (see Apple Developer Library)
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
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.
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.
None of that worked for me, so here is a working solution...
In Info.plist, add a row:
UIViewControllerBasedStatusBarAppearance, and set the value NO.
Then in AppDelegate in didFinishLaunchingWithOptions, add these rows:
[application setStatusBarHidden:NO];
[application setStatusBarStyle:UIStatusBarStyleLightContent];
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:
& 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:
Thats it.
Just two steps as following:
Step 1:
Under the Info tab of the project target, Add Row:
UIViewControllerBasedStatusBarAppearance, set value NO.
Step 2:
In the project AppDelegate.m:
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
…
[application setStatusBarStyle:UIStatusBarStyleLightContent];
…
}
This works in Golden Master iOS 7 and Xcode 5 GM seed and iOS7 SDK released on September 18th, 2013 (at least with navigation controller hidden):
Set the UIViewControllerBasedStatusBarAppearance to NO in the
Info.plist.
In ViewDidLoad method or anywhere, where do you want to change
status bar style:
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
In case your UIViewController is inside a UINavigationController you will have to set the BarStyle:
-[UINavigationBar setBarStyle:UIBarStyleBlack]
Original Answer is here
https://devforums.apple.com/message/844264#844264
If you have an embedded navigation controller created via Interface Builder, be sure to set the following in a class that manages your navigation controller:
-(UIStatusBarStyle)preferredStatusBarStyle{
return UIStatusBarStyleLightContent;
}
That should be all you need.
I'm using Xcode 6 beta 5 on a Swift project, for an iOS 7 app.
Here is what I did, and it works:
info.plist:
Go to Project -> Target,
Then set Status Bar Style to Light. It makes status-bar white from the launch screen.
Then set View controller-based status bar appearance equal to NO 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
}
In AppDelegate.m, add the following.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
}
And in the Plist file, set 'View controller-based status bar appearance' to NO.
Simply In App Delegate:
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
In Swift 5, Follow the below steps:
Add key UIViewControllerBasedStatusBarAppearance and set value to false in Info.plist
Add key UIStatusBarStyle and set value to UIStatusBarStyleLightContent
Well, this is really working like a piece of cake for me.
Go to your app's info.plist.
Set View controller-based status bar appearance to NO
Set Status bar style to UIStatusBarStyleLightContent
Then go to your app's delegate and paste in the following code where you set your windows's RootViewController.
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"7.0"))
{
UIView *view=[[UIView alloc] initWithFrame:CGRectMake(0, 0,320, 20)];
view.backgroundColor=[UIColor colorWithRed:0/255.0 green:0/255.0 blue:0/255.0 alpha:1.0];
[self.window.rootViewController.view addSubview:view];
}
Bingo. It's working for me.
iOS 7 allows individual view controllers to determine the appearance of the status bar, as described by the Apple developer documentation:
iOS 7 gives view controllers the ability to adjust the style of the status bar while the app is running. A good way to change the status bar style dynamically is to implement preferredStatusBarStyle and—within an animation block—update the status bar appearance and call setNeedsStatusBarAppearanceUpdate.
Setting the status bar appearance globally is a two-step process.
First, you need to tell iOS that you don't want to set the status bar appearance on a view-by-view basis.
Then you need to take charge and actually set the new global status bar style.
To disable view-by-view status bar control, you'll need to set the View controller-based status bar appearance property in Info.plist.
Open the Project Navigator and select the project for your iOS app, then select the Info tab.
Hover over a row, then click the plus sign that appears to add a new property to your .plist.
Enter View controller-based status bar appearance in the Key field, then make sure the Type field is set to Boolean. Finally, enter NO in the Value field.
To set a global style for the status bar, add another property under the Info tab with a key of Status bar style, a Type of String and a Value of Opaque black style.
Here's a blog post with a little more detail and some sample code:
http://codebleep.com/setting-the-status-bar-text-color-in-ios-7/
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:
Open your Info.plist.
Add key UIViewControllerBasedStatusBarAppearance and set value to No (false). The human readable version of this is "View controller-based status bar appearance".
Add key UIStatusBarStyle and set value to UIStatusBarStyleLightContent (i.e., "Light Content").
Answer updated for for Xcode GM Seed:
In Info.plist put View controller-based status bar appearance as NO
In the project, set:
In ViewDidLoad:
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
No need do some extra , just write this code in your viewController and get status bar color white
- (UIStatusBarStyle)preferredStatusBarStyle{return UIStatusBarStyleLightContent;}
I think all the answers do not really point the problem because all of them work in specific scenarios. But if you need to cover all the cases follow the points bellow:
Depending on where you need the status bar light style you should always have in mind these 3 points:
1)If you need the status bar at the launch screen or in other places, where you can't control it (not in view controllers, but rather some system controlled elements/moments like Launch Screen)
You go to your project settings
2) if you have a controller inside a navigation controller
You can change it in the interface builder as follows:
a) Select the navigation bar of your navigation controller
b) Then set the style of the navigation bar to "Black", because this means you'll have a "black" -> dark background under your status bar, so it will set the status bar to white
Or do it in code as follows
navigationController?.navigationBar.barStyle = UIBarStyle.Black
3) If you have the controller alone that needs to have it's own status bar style and it's not embedded in some container structure as a UINavigationController
Set the status bar style in code for the controller:
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
}
Set value of .plist according to status bar style setup level.
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:
This is documented in the iOS 7 UI Transition Guide, which you need an Apple developer ID to access directly. The relevant excerpt:
Because the status bar is transparent, the view behind it shows through. [...] Use a UIStatusBarStyle constant to specify whether the statusbar content should be dark or light:
UIStatusBarStyleDefault displays dark content. [...]
UIStatusBarStyleLightContent displays light content. Use when dark content is behind the status bar.
Also possibly of interest:
In iOS 7, you can control the style of the status bar from an individual vew controller and change it while the app runs. To opt in to this behavior, add the UIViewControllerBasedStatusBarAppearance key to an app's Info.plist file and give it the value YES.
I'd definitely recommend having a look through the document, which, again, you can access with your Apple developer ID.
Simply calling
[[UINavigationBar appearance] setBarStyle:UIBarStyleBlack];
in the
-(BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
}
method of my AppDelegate works great for me in iOS7.
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
}
I did some things different and it works for me.
With no changes in code, I did config my .plist file like this:
View controller-based status bar appearance > NO
Status bar style > UIStatusBarStyleLightContent (simple string)
I hope it helps.
edit
For each view controller I change the "status bar"'s Simulated Metrics property, in storyboard, from "inferred" to "Light Content"
in info.plist set the field value NO View controller-based status bar appearance and set statusbar style light in target > general setting.
Just to summarize, edit your project Info.plist and add:
View controller-based status bar appearance : NO
Status bar style : Opaque black style
or if you have raw key/value plist
UIViewControllerBasedStatusBarAppearance : NO
UIStatusBarStyle : Opaque black style
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 :-) !

Resources