I want to change the status bar style on a per-ViewController level on iOS 13. So far I didn't have any luck.
I define UIUserInterfaceStyle
as Light
in info.plist (as I do not want to support dark mode) and set UIViewControllerBasedStatusBarAppearance
to true
. preferredStatusBarStyle
is called on my ViewController but completely ignored. The UIUserInterfaceStyle
seems to always override the VC preferences.
How do I get per-ViewController status bar style working on iOS 13? Or is it not supported any more?
5 Answers
iOS 13.2, Swift 5.1
For me nothing worked from solutions mentioned before. After 5 hours I ended up on modalPresentationCapturesStatusBarAppearance flag .
destinationNavigationController.modalPresentationCapturesStatusBarAppearance = true
sourceViewController.present(destinationNavigationController, animated: animated, completion: nil)
After this preferredStatusBarStyle
was called in presented VC.
override var preferredStatusBarStyle: UIStatusBarStyle {
if #available(iOS 13.0, *) {
if traitCollection.userInterfaceStyle == .light {
return .darkContent
} else {
return .lightContent
}
} else {
return .lightContent
}
}
I had the same issue on iOS13 while it was fine on iOS12 for my app. I have a TabBarController which holds 3 NavigationBarControllers, and I present TabBarController from a previous ViewController. I fixed it by setting .modalPresentationStyle to .fullScreen when presenting:
tabbarController.modalPresentationStyle = .fullScreen
Maybe it will help you somehow...
In my case, I had a similar issue with incorrect UIStatusBarStyle
. For some view controllers in my app, I need to set a dark status bar style ignoring current system color mode. The problem was I used .default
value, but in iOS 13 it changes depending on the context. That's why I added a small workaround to handle both iOS 12- and iOS 13+ cases.
private extension UIStatusBarStyle {
static var darkContentWorkaround: UIStatusBarStyle {
if #available(iOS 13.0, *) {
return .darkContent
} else {
return .default
}
}
}
i had the same problem on iOS 13 while using navigation controller i was able to change the status bar color using
let navBarAppearance = UINavigationBarAppearance()
navigationBar.scrollEdgeAppearance = navBarAppearance
but the problem was when i was using present controller the status bar didn't change i used this code on top view controller
override func viewDidAppear(_ animated: Bool) {
if #available(iOS 13, *)
{
let statusBar = UIView(frame: (UIApplication.shared.keyWindow?.windowScene?.statusBarManager?.statusBarFrame)!)
statusBar.backgroundColor = UIColor.systemBackground
UIApplication.shared.keyWindow?.addSubview(statusBar)
}
}
you can use your color in "UIColor.systemBackground"
preferredStatusBarStyle
for each of the view controllers. Note that only top view controllers matter, not embedded ones. So it will work with controller you present but not with controller you for instance push on your navigation controller. To make navigation controller work as well you will need to subclass it forward the setting. – Matic Oblakextension UITabBarController { open override var childForStatusBarStyle: UIViewController? { return selectedViewController?.childForStatusBarStyle ?? selectedViewController } } extension UINavigationController { open override var childForStatusBarStyle: UIViewController? { return topViewController?.childForStatusBarStyle ?? topViewController } }
As I said,preferredStatusBarStyle
is called but just ignored. – Micky@available(iOS 13.0, *)
code and I have to implement the AppDelegate methods again. – DoesData