Reputation: 177
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:
View controller-based status bar appearance
in Info.plist
to YES.preferredStatusBarStyle
property for every view controller that can be displayed by NAV including VC.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
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.
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
Then of course make a DarkBaseViewController
and make the status bar dark by making statusBarStyle
property back to default.
UIApplication.shared.statusBarStyle = .default
Subclass either the dark or light base view controllers.
Finally, set this property to NO in your info.plist:
View controller-based status bar appearance
Hope this helps.
Upvotes: 3