preferrefstatusbarstyle not working in uiviewcontroller - ios

override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent}
Using swift 3, I use setstatusbarstyle in my appdelegate and it works, but gives me warning that its deprecated starting ios 9.So am using this in my view controller, and its not working.I printed since the method as well, and it did not print.

Add View controller-based status bar appearance bool to No in your plist file. And then in General Settings of your target Status bar style to Light.

Related

How to change status bar style - iOS 12

I need to update status bar style on every view controller based on the background color (what UINavigationController is doing automatically).
Have tried all the options described on stackoverflow (View controller-based status bar appearance in info.plist set to YES), but none worked for me.
I am using Xcode 10 beta 6 and Swift 4.2, targeting iOS 12.
Swift 4+, iOS 12+
View controller-based status bar appearance now needs to be set to YES in info.plist since UIKit no longer wants us to edit status bar style through UIApplication.shared—status bar style is now view-controller based.
Then if you want the change to be applied at app level, simply override preferredStatusBarStyle in the appropriate container view controller (ideally the root)...
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
...and this will propagate to all view controllers underneath it. And if you want to edit status bar style per view controller, apply this override per view controller.
If status bar style ever changes during runtime, then you need to call setNeedsStatusBarAppearanceUpdate() (from anywhere in the container/root view controller or that specific view controller), otherwise it isn't needed.
Set View controller-based status bar appearance to NO in the info.plist and override preferredStatusBarStyle in each view controller like so:
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
And call setNeedsStatusBarAppearanceUpdate() in your view controller (in viewDidLoad() for example).
If you have View controller-based status bar appearance in info.plist set to YES and your view controller is embedded into UINavigationController, then your navigation controller will be responsible for updating bar style (through navigationController.navigationBar.barStyle) and preferredStatusBarStyle property will be ignored
I have Xcode 10.2 and found as you did that setting the View controller-based status bar appearance in info.plist to "YES" will not change the status bar style at all.
However, I did find that changing two keys in the info.plist file will do all the work of changing the status bar to light or dark without any additional coding.
Here's what I did to fix it for myself
When hovering over the top line "Information Property List" from the info.plist file, a small round "+" button will appear. Click this button and scroll through the items until you find the following keys.
View controller-based status bar appearance [set this value to] NO
Status bar style [set this value to] UIStatusBarStyleLightContent
NOTE: The UIStatusBarStyleLightContent is not found as a selectable item in the value list and must be typed into the value box.
I hope this helps you or anyone else looking for an answer to this question.
If you're wrapped in a nav controller, you're going to need this:
final class LightNavigationController: UINavigationController {
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
}
override func viewDidLoad(){
super.viewDidLoad()
navigationController?.navigationBar.barStyle = .default
}
override var prefersStatusBarHidden: Bool {
return true
}
I applied scroll view also in the same screen, by this code was able to resolve status bar issue.

Set status bar style in Xcode 10

I'm using Xcode Version 10.0 beta 4. I keep getting this warning Setter for 'statusBarStyle' was deprecated in iOS 9.0: Use -[UIViewController preferredStatusBarStyle].
I change the status bar style in my scrollViewDidScroll function with UIApplication.shared.statusBarStyle = .default after the user has scrolled down far enough. Is there any way I can continue to do this without receiving this warning?
What you have been doing was always wrong; it's just that the expected deprecation has finally come.
Do what the error message says. Implement preferredStatusBarStyle in the top-level view controller (or some view controller that it consults). When the value changes, call setNeedsStatusBarAppearanceUpdate so that preferredStatusBarStyle will be consulted again.
Actually statusBarStyle was deprecated, use below code in AppDelegate to remove the warning.
var darkMode = false
var preferredStatusBarStyle : UIStatusBarStyle {
return darkMode ? .default : .lightContent
}

iOS: Default status bar style with UIViewControllerBasedStatusBarAppearance YES

Is there a way how to set the default status bar style while keeping the UIViewControllerBasedStatusBarAppearance enabled?
Here is the problem, I'm dealing with:
Nearly the whole app needs to be using UIStatusBarStyle.LightContent as the navigation bar has a dark background. Originally, UIViewControllerBasedStatusBarAppearance was disabled and the following was set in in Info.plist for while text status status bar:
<key>UIStatusBarStyle</key>
<string>UIStatusBarStyleLightContent</string>
This worked just fine until I found out that this .LightContent status bar is shown even for some of the share extensions, like Facebook Messenger, causing it to be unreadable:
This could be solved by using UIViewControllerBasedStatusBarAppearance, but then I would need to add the following method to all of view controllers which I want to avoid as the app is quite large.
Moreover, for the one screen in the app that has light nav bar background, I was switching to dark nav bar using UIApplication.sharedApplication().setStatusBarStyle() but this method in deprecated in iOS 9.
Any ideas how to solve this? Swizzling?
Solution
The easiest and cleanest way how to achieve that is to add the following line in AppDelegate's application:willFinishLaunchingWithOptions method:
UINavigationBar.appearance().barStyle = .Black
This will make .LightContent as the default status bar style thorough the app as long as your app uses UINavigationController.
Don't forget to keep the following setting in app's Info.plist if want to use .LightContent status bar style during launch for splash screen:
<key>UIStatusBarStyle</key>
<string>UIStatusBarStyleLightContent</string>
TL;DR
My current setup, which is very similar to many other apps, uses UITabBarController as the top most controller with UINavigationController stack for each tab.
UINavigationController takes care of the status bar style (as it should) and do not call preferredStatusBarStyle() on its child view controllers. Therefore, implementing the subclassing solution proposed by par does not work in my case.
Further subclassing the custom subclass of UINavigationController I'm using would not be a clean solution either.
Now, since the app has UIViewControllerBasedStatusBarAppearance enabled and correct status bar style everywhere in the app itself, SFSafariViewController and share extension like Messages, Mail, etc use the correct (.Default) status bar style too.
The only exception where the correct status bar style is not used is the Facebook Messenger's share extension mentioned in the question. However, it seems to be a bug in the extension itself as all apps I have tried that use .LightContent status bar style (like Twitter, for example) have the same issue - presented FB Messenger share extension from the app has a status bar with white color text.
A solution I use quite frequently is to create a base view controller class that all view controllers in my app derive from. This has the advantage of allowing use of the view-controller-based status bar style-setting functionality with a default (light or dark) style, which can then be overridden on a per-view-controller basis as necessary.
A base view controller is also really handy once you start getting into trait-collection based changes, custom transition animations that you want for most view controllers, a central point for analytics tracking, and other useful things.
Yes, you have to go through your potentially large source base and change all your UIViewControllers into BaseViewControllers, but this is often as easy as a global search-and-replace.
Here's what the BaseViewController looks like with status-bar related methods:
class BaseViewController: UIViewController {
var statusBarHidden: Bool = false { didSet { setNeedsStatusBarAppearanceUpdate() } }
var statusBarStyle: UIStatusBarStyle = .lightContent { didSet { setNeedsStatusBarAppearanceUpdate() } }
var statusBarUpdateAnimation: UIStatusBarAnimation = .fade { didSet { setNeedsStatusBarAppearanceUpdate() } }
override var preferredStatusBarStyle: UIStatusBarStyle { return statusBarStyle }
override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation { return statusBarUpdateAnimation }
override var prefersStatusBarHidden: Bool { return statusBarHidden }
}
For all view controllers that use the default light style, you don't need to do anything special:
class ViewController: BaseViewController { }
In the cases where you need a dark status bar, do:
class DarkStatusBarViewController: BaseViewController {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
statusBarStyle = .default
}
}
Note also that you could rename the DarkStatusBarViewController above to DarkStatusBarBaseViewController and derive from it instead of BaseViewController when you need a dark status bar. Then you don't need to duplicate the status bar code in every view controller that needs it and you maintain a nice linear relationship for all your BaseViewController functionality.

UISearchController resets the status bar style to .Default when the search bar becomes the first responder

I'm using a UISearchController and adding its search bar to a table view controller's header:
The issues I'm facing is that when the user starts to type into the search bar, making it the first responder, then the status bar style is reverting to the .Default:
I'm using preferredStatusBarStyle() to set the style in the view controller. If instead I use the info.plist to set the style and additionally set the 'View Controller Based Status Appearance' key to NO, then the style stays as Light.
However it is not an option to set the 'View Controller Based Status Appearance' key to NO as I have some VCs that require the default style and some that require the light style.
I tried resetting the style to light on a search bar delegate method (which gets invoked when it becomes first responder) i.e.:
func searchBarShouldBeginEditing(searchBar: UISearchBar) -> Bool
{
UIApplication.sharedApplication().statusBarStyle = .LightContent
self.setNeedsStatusBarAppearanceUpdate()
return true
}
But that didn't work either.
Any suggestions?
I don't know if there's another way, but I solved it by implementing a UISearchController derived class and using that instead:
class MySearchController : UISearchController
{
// various init overrides ...
override func preferredStatusBarStyle() -> UIStatusBarStyle {
return .LightContent
}
}
Or if a navigation controller is being used then this will prevent preferredStatusBarStyle() from being called, in which case use this instead:
UIApplication.sharedApplication().statusBarStyle = .LightContent
AND
Make sure in the info.plist "View controller-based status bar appearance" is set to NO.
Update for SWIFT 3.0
When a navigation controller is being called:
UIApplication.shared.statusBarStyle = .lightContent (on viewDidLoad)
+
set View controller-based status bar appearance = NO on info.plist

When searchController is active, status bar style changes

Throughout my app I have set the status bar style to light content.
However, when the search controller is active, it resets to the default style:
I have tried everything to fix this, including checking if the search controller is active in an if statement, and then changing the tint color of the navigation bar to white, and setting the status bar style to light content. How do I fix this?
a couple of option, and this could be a problem that is a bug, but in the mean time, have you tried this:
Option 1:
info.plist, set up the option in your info.plist for "Status bar style", this is a string value with the value of "UIStatusBarStyleLightContent"
Also, in your infor.plist, set up the variable "View controller-based status bar appearance" and set it's value to "NO"
Then, in each view controller in your app, explicitly declare the following in command in your initializers, your ViewWillAppear, and your ViewDidLoad
UIApplication.sharedApplication().statusBarStyle = UIStatusBarStyle.LightContent
Option 2:
In your info.plist set up the option for "Status bar style" to "UIStatusBarStyleLightContent". Also, in your infor.plist, set up the variable "View controller-based status bar appearance" and set it's value to "YES"
Then, in each view controller place the following methods
override func preferredStatusBarStyle() -> UIStatusBarStyle {
return UIStatusBarStyle.LightContent;
}
override func prefersStatusBarHidden() -> Bool {
return false
}
Also, you may need to do something like this:
self.extendedLayoutIncludesOpaqueBars = true
Also, I translated it to Swift code for you
Add this to your code to make the status bar style to Light :
override func preferredStatusBarStyle() -> UIStatusBarStyle {
return UIStatusBarStyle.LightContent;
}
You can also set the status bar in the info list and it will remain same in you app until it is override in the code for paticular view controller.

Resources