The problem you're experiencing is that UINavigationController
doesn't defer the choice of status bar to its view controllers.
Instead, for a navigation controller, the status bar style can be set by adjusting the barStyle
property of its navigationBar
.
If it is set to a black style, then the status bar will be light style:
navigationController?.navigationBar.barStyle = .black
Note, that this will also change the color of the navigationBar
, however you can still set the bar's colour to whatever you want using barTintColor
:
navigationController?.navigationBar.barTintColor = .purple
If you want to make a global change, so that all instances of UINavigationController
use the same status bar style (useful if you've got multiple tabs all of which use a navigation controller), then you can add an extension on UINavigationController
and override the preferredStatusBarStyle
property:
extension UINavigationController {
open override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
}
A final option, is to defer the choice to the view controllers in the navigation controller's stack.
To do that, override the childViewControllerForStatusBarStyle
property of your navigation controller extension and have it return the topViewController
:
extension UINavigationController {
open override var childViewControllerForStatusBarStyle: UIViewController? {
return topViewController
}
}
In this case, you'll need to override preferredStatusBarStyle
in all of your view controllers (not the optimal approach, but it's an option if you need this granular level of control on a per-child-controller basis).
All of these solutions require that your View controller-based status bar appearance
key in Info.plist is set to YES
.