
By Stan Chang · · Updated · 2 min read · #ios-development
Status Bar Style Not Changing in UIKit
A current checklist for pushed and presented view controllers
When a status bar style does not change after a push or presentation, the usual problem is ownership. UIKit asks a particular view controller for the preferred style. An override on some other controller in the hierarchy has no effect.
Return the style from the active view controller
Override preferredStatusBarStyle on the controller that should own the appearance:
final class CustomViewController: UIViewController {
private var usesLightStatusBar = true
override var preferredStatusBarStyle: UIStatusBarStyle {
usesLightStatusBar ? .lightContent : .darkContent
}
func setUsesLightStatusBar(_ value: Bool) {
usesLightStatusBar = value
setNeedsStatusBarAppearanceUpdate()
}
}
If the value changes while the controller is visible, call setNeedsStatusBarAppearanceUpdate(). Returning a new value alone does not ask UIKit to query it again.
Forward ownership through a container
A container view controller can choose which child supplies the status bar style. If a pushed controller’s override is ignored, make the ownership explicit with childForStatusBarStyle. For example, a navigation-controller subclass can forward the query to its top controller:
final class StatusBarNavigationController: UINavigationController {
override var childForStatusBarStyle: UIViewController? {
topViewController
}
}
Use the same pattern in a custom container, returning whichever child currently owns the visible content. When that child changes, ask the container to update the status bar appearance.
Capture a non-fullscreen presentation
A fullscreen presentation takes over status bar appearance. A custom, sheet, or other non-fullscreen presentation may leave control with the presenting controller. Set modalPresentationCapturesStatusBarAppearance when the presented controller should take ownership:
let presented = CustomViewController()
presented.modalPresentationStyle = .custom
presented.modalPresentationCapturesStatusBarAppearance = true
present(presented, animated: true)
Debugging checklist
- In
Info.plist, confirmUIViewControllerBasedStatusBarAppearanceis absent (the default istrue) or set totrue. When it isfalse, UIKit uses the app-level status bar style instead of the current controller’spreferredStatusBarStyle, so this controller-based checklist does not apply. - Confirm the override is on the controller UIKit actually consults.
- If the style changes at runtime, call
setNeedsStatusBarAppearanceUpdate(). - If a container owns the screen, return the intended child from
childForStatusBarStyle. - If a non-fullscreen presentation should control the style, enable
modalPresentationCapturesStatusBarAppearance. - Check the content behind the status bar separately.
preferredStatusBarStylechanges the foreground style, not the background color or safe-area layout.
This is a UIKit guide. SwiftUI screens have a different ownership model and should not copy these container overrides blindly.