Igor Andreev
Igor Andreev

Reputation: 177

Unable to change status bar style

I have a UIViewController VC, which embedded in UINavigationController NAV. The NavigationController is embedded in UITabBarController TAB. Now, I need every view controller in my app but VC to have .default status bar style. VC has to have lightContent status bar style.

What I’ve done to achieve the desired effect:

  1. Set View controller-based status bar appearance in Info.plist to YES.
  2. Overriden preferredStatusBarStyle property for every view controller that can be displayed by NAV including VC.
  3. Put setNeedsStatusBarUpdate() into viewDidLoad() of every view controller that can be displayed by NAV including VC.

Such an approach resulted in nothing.

Since TAB is initial view controller inside my Main.storyboard and everything is essentially displayed through it, I thought that maybe I can change status bar through it. So I’ve written the following inside TAB description:

//  MARK: Status bar
///
private var requiredStatusBarStyle: UIStatusBarStyle = .default
//
override var preferredStatusBarStyle: UIStatusBarStyle { get { return self.requiredStatusBarStyle } }
///
func setStatusBarStyle(_ style: UIStatusBarStyle)
{
    requiredStatusBarStyle = style
    DispatchQueue.main.async
    {
        self.setNeedsStatusBarAppearanceUpdate()
    }
}  

And then invoked setStatusBarStyle method of TAB by every view controller that can be displayed by NAV including VC in viewWillAppear method. This resulted in nothing as well. Funny thing is invoking setStatusBarStyle inside TAB’s viewDidLoad does nothing too.

Well, if it's not TAB that is preventing me from changing style, maybe NAV is? So I've made the following extension:

struct UINavigationControllerExtensionKeys
{
    static var UIStatusBarStyleKey: UInt8 = 0
}

extension UINavigationController
{
    private var requiredStatusBarStyle: UIStatusBarStyle
    {
        get
        {
            guard let style = objc_getAssociatedObject(self, &UINavigationControllerExtensionKeys.UIStatusBarStyleKey) as? UIStatusBarStyle else
            {
                return .default
            }
            return style
        }
        set (style)
        {
            objc_setAssociatedObject(self, &UINavigationControllerExtensionKeys.UIStatusBarStyleKey, style, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }

    open override var preferredStatusBarStyle: UIStatusBarStyle { get { return self.requiredStatusBarStyle } }

    func setStatusBarStyle(_ style: UIStatusBarStyle)
    {
        requiredStatusBarStyle = style
        DispatchQueue.main.async
        {
            self.setNeedsStatusBarAppearanceUpdate()
        }        
    }
}

And then invoked setStatusBarStyle method of NAV by every child view controller of it in viewWillAppear method. No luck as well.

It is obvious that I'm overcomplicationg things here. But for some reason answers poroposed here and here do not work for me. I am lost here people. Please help.

Upvotes: 1

Views: 857

Answers (1)

Glenn Posadas
Glenn Posadas

Reputation: 13283

Now, I need every view controller in my app but VC to have .default status bar style. VC has to have lightContent status bar style.

For me, you're merely giving yourself a headache with your approaches. Here's my take and it will be lot easier.

  1. Make a LightBaseViewController: UIViewController or whatever base class name you want for all the viewControllers you want to have the light status bar, and put this in LightBaseViewController's viewWillAppear:

    UIApplication.shared.statusBarStyle = .lightContent
    
  2. Then of course make a DarkBaseViewController and make the status bar dark by making statusBarStyle property back to default.

    UIApplication.shared.statusBarStyle = .default
    
  3. Subclass either the dark or light base view controllers.

  4. Finally, set this property to NO in your info.plist:

    View controller-based status bar appearance
    

Hope this helps.

Upvotes: 3

Related Questions