Can not override the preferredStatusBarStyle - swift

In dark mode style, the status bar disappear cause of dark color.
I added the:
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
but the problem is, when I add the method in "viewDidLoad" I get the error:
override can only be specified in class member
any idea how to resolve this?

preferredStatusBarStyle is a member of the UIViewController class. What you want to do here is to override this class member. The snippet in your question have nothing to do in the viewDidLoad method and should be placed in your subclass body like this :
class YourViewController: UIViewController {
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
override func viewDidLoad() {
super.viewDidLoad()
}
}

I am going to answer the question here, maybe it can help someone else:
After hours checking my codes, I found out that I have rootViewController which I used as a authentication then after the authentication user pass to TabbarViewController... which is not rootViewController, I added the:
preferredStatusBarStyle
To my rootViewController and it works.
View controller-based status bar appearance should be
YES

Related

What is the correct way to manage statusBarStyle in Swift?

I've tried adding key UIViewControllerBasedStatusBarAppearance to true inside info.plist file and then added the below code inside UINavigationController class which holds several UIViewController classes.
class HomeNavigationController: UINavigationController {
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
}
But, it did not work.
I've also tried setting the barStyle property of navigationBar to .black but that too didn't work either.
Also looked up to https://stackoverflow.com/a/58203998/9180494, but that did not help as well.
Please NOTE: For UIViewController classes not embedded inside any UINavigationController , if I use computed property preferredStatusBarStyle, then it works.
Try in viewDidAppear() of UINavigationController class:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
navigationController?.navigationBar.barStyle = .black
}
Also add (in the same class as above):
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
#Anuranjan Bose Try this on your view did load,
override func viewDidLoad() {
super.viewDidLoad()
setNeedsStatusBarAppearanceUpdate()
}

Attempting to Change the UIStatusBar Tint Color

I am trying to change the UIStatusBar tint color in a specific UIViewController.
Here is my code:
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
self.setNeedsStatusBarAppearanceUpdate()
}
Nothing is happening.
On a UINavigationController, preferredStatusBarStyle is not called because its topViewController is preferred to self. So, to get preferredStatusBarStyle called on an UINavigationController, you need to change its childViewControllerForStatusBarStyle.
To do it for one UINavigationController:
class MyRootNavigationController: UINavigationController {
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
override var childViewControllerForStatusBarStyle: UIViewController? {
return nil
}
}
You can add an extension to UINavigationController:
extension UINavigationController {
open override var childForStatusBarStyle: UIViewController? {
return visibleViewController
}
}
Then for view controllers that you want a light status bar (white time, icons etc.), then override preferredStatusBarStyle:
override var preferredStatusBarStyle: UIStatusBarStyle {
return UIStatusBarStyle.lightContent
}
For a dark status bar, you don't have to do anything.
You may need to add "View controller-based status bar appearance" with a value of "YES" in your info.plist

UIStatusBarStyle doesn't change

I'm working on a swift app and I wanna change the UIStatusBarStyle according to the app's theme (there are 2 options - light and dark theme). I have set View controller-based status bar appearance to NO in the info.plist and in the UIViewController I tried to set it based on the current theme like so:
override var preferredStatusBarStyle: UIStatusBarStyle {
return Theme.current.statusBarStyle
}
protocol ThemeProtocol {
// Status Bar
var statusBarStyle: UIStatusBarStyle { get }
}
class Theme {
static var current: ThemeProtocol = LightTheme()
}
class LightTheme: ThemeProtocol {
// Status Bar
var statusBarStyle: UIStatusBarStyle = .default
}
class DarkTheme: ThemeProtocol {
// Status Bar
var statusBarStyle: UIStatusBarStyle = .lightContent
}
No result really. I tried to test it by returning only: return .lightContent but that didn't change the status bar either.
What am I doing wrong?
UPDATE:
Okay, so this is what I'm trying to do and it's not working.
fileprivate func applyTheme() {
statusBarStyle = UserDefaults.standard.bool(forKey: SelectedThemeKey) ? .default : .lightContent
self.setNeedsStatusBarAppearanceUpdate()
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return statusBarStyle
}
And it's not working. Despite changing the theme, the status bar always remain with the default style. applyTheme() is called in viewDidLoad() and viewWillAppear()
You need to call this method after any change
setNeedsStatusBarAppearanceUpdate()
//
class ViewController: UIViewController {
var current = UIStatusBarStyle.default
#IBAction func changeClicked(_ sender: Any) {
current = current == .default ? .lightContent : .default
self.setNeedsStatusBarAppearanceUpdate()
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return current
}
}
First of all, your code makes no sense. You say
I have set View controller-based status bar appearance to NO in the info.plist and in the UIViewController I tried to set it
So on the one hand you tell the runtime, do not listen to my view controller. Then you complain when the runtime doesn't listen to your view controller!
Second, keep in mind that your view controller gets no say in the status bar appearance unless it is the top-level view controller (or the top-level view controller deliberately defers to it). If your view controller is inside a navigation controller, for example, its statusBarStyle is completely irrelevant.
First
if you are trying to change StatusBarStyle with UIApplication.shared.statusBarStyle = .default, then you should set
View controller-based status bar appearance to be NO.
in this way, you need to control UIApplication.shared.statusBarStyle by yourself in everywhere; e.g viewWillAppear / viewWillDisappear.
but this method is deprecated after iOS 9.
Now I suggest you learn the new way:
please set View controller-based status bar appearance to be YES, and
override UIViewController's preferredStatusBarStyle to handle it.
override var preferredStatusBarStyle: UIStatusBarStyle {
return .default
}
but it still not working, why?
in your case, I guess that UIViewController is one of viewControllers of UINavigationController.
if you used UINavigationController, you should override preferredStatusBarStyle in UINavigationController.
maybe you will say that I need to set different status bar style with difference view controllers, it is okay.
Just override childForStatusBarStyle in UINavigationController like this
override var childForStatusBarStyle: UIViewController? {
return topViewController
}
then override preferredStatusBarStyle in UIViewController you want to change.
you can also make it by extension like this
extension UINavigationController {
override open var childForStatusBarStyle: UIViewController? {
return topViewController
}
}

Opening a side menu on click on a TAB bar in SWIFT

I want to make something like below snapshots.
When I click on profile tab bar instead of opening a new view controller it shows a side menu. Is it something that has been handled on click of tabbar ?
if you want to achieve something like your screenShot then you are using a wrong library, because when you show your right viewController the front viewController go to left by amount of width of your right viewController, but anyways here is the code for what you need to do
first you need to put your viewController as delegate of your TabBarViewController and in func tabBarController(tabBarController: UITabBarController, shouldSelectViewController viewController: UIViewController) -> Bool you need to return false and call the method of SWRevealViewController to show right viewController rightRevealToggleAnimated(true)
class FirstViewController: UIViewController,SWRevealViewControllerDelegate,UITabBarControllerDelegate {
#IBOutlet weak var sliderControl: UISlider!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.revealViewController().delegate = self
self.tabBarController?.delegate = self
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
//self.view.removeGestureRecognizer(self.revealViewController().panGestureRecognizer())
//self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tabBarController(tabBarController: UITabBarController, shouldSelectViewController viewController: UIViewController) -> Bool {
//checking for specific viewController
if(viewController is DesiredViewControllerClass) {
self.revealViewController().rightRevealToggleAnimated(true)
}
return false
}
}
I hope this helps you, regards
You can use the tab bar delegate:
extension ViewController: UITabBarDelegate {
func tabBar(tabBar: UITabBar, didSelectItem item: UITabBarItem) {
// Present hamburger menu
}
}

extension for UIViewController is not Working change UIStatusBarStyle In Swift

I am Try to Create extension for UIViewController but Its not working . i am changing status bar color for using extension but i cant get success. But without extension is working. I am new in Extension Please help me.
My Aim is I DONT WANT TO CREATE FUNCTION ON EVERY VIEW CONTROLLER , REDUSE REUSABILITY
Create Extension Is Not Working
extension UIViewController {
func preferredStatusBarStyle_change() -> UIStatusBarStyle {
return UIStatusBarStyle.LightContent
}
}
//!!!!!!!!!view1
override func viewDidLoad() {
super.viewDidLoad()
//preferredStatusBarStyle();
self.preferredStatusBarStyle_change();
}
//!!!!!!!!!view2
override func viewDidLoad() {
super.viewDidLoad()
//preferredStatusBarStyle();
self.preferredStatusBarStyle_change();
}
Without Extension IS Working
View1
override func viewDidLoad() {
super.viewDidLoad()
preferredStatusBarStyle();
}
override func preferredStatusBarStyle() -> UIStatusBarStyle {
return UIStatusBarStyle.LightContent
}
View2
override func viewDidLoad() {
super.viewDidLoad()
preferredStatusBarStyle();
}
override func preferredStatusBarStyle() -> UIStatusBarStyle {
return UIStatusBarStyle.LightContent
}
Help me Try to understanding Reusability and extension
It not working because:
Viewcontroller will call preferredStatusBarStyle() for define about statusbar. Actually you remove preferredStatusBarStyle(); in viewDidload, your controller still work.
So in your case you can resolve like this:
You create a subclass of UIViewController maybe name it is: BaseViewController and it this class you put:
override func preferredStatusBarStyle() -> UIStatusBarStyle {
return UIStatusBarStyle.LightContent
}
And now all your ViewController you inherited from BaseViewController status bar will always .LightContent you don't need put this code above every where.
Demo: Demo