Swift
iOS Development
preferredStatusBarStyle
Xcode
Apple Developer

preferredStatusBarStyle isn't called

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

When preferredStatusBarStyle is not being called, the problem is usually not the method itself. The problem is that the wrong view controller owns status bar appearance, or the app is configured to manage the status bar globally instead of per controller.

The fix is usually one of three things: enable controller-based status bar appearance, ask the correct container controller to forward the request, or call setNeedsStatusBarAppearanceUpdate() at the right time.

Make Sure View Controllers Control the Status Bar

First check Info.plist. If UIViewControllerBasedStatusBarAppearance is disabled, your individual view controller's override may never matter.

The usual working setup is:

xml
<key>UIViewControllerBasedStatusBarAppearance</key>
<true/>

With that in place, a normal override looks like this:

swift
1import UIKit
2
3final class DetailsViewController: UIViewController {
4    override var preferredStatusBarStyle: UIStatusBarStyle {
5        .lightContent
6    }
7}

If the method still is not called, the next thing to inspect is the controller hierarchy.

Container Controllers Often Own the Decision

If your screen is inside a UINavigationController, UITabBarController, or another container, the container may be the one asked about the status bar style.

A common fix is to forward the style request to the visible child:

swift
1import UIKit
2
3final class HostingNavigationController: UINavigationController {
4    override var childForStatusBarStyle: UIViewController? {
5        visibleViewController
6    }
7}

Now the top view controller gets to decide its own style.

Without this forwarding behavior, you can override preferredStatusBarStyle in your child controller all day and still never see it used.

Trigger an Update When the Style Changes

If the desired status bar style changes after the controller is already on screen, tell UIKit to ask again:

swift
1override func viewWillAppear(_ animated: Bool) {
2    super.viewWillAppear(animated)
3    setNeedsStatusBarAppearanceUpdate()
4}

You may also call it after theme changes, modal presentation changes, or navigation transitions that affect the background behind the status bar.

The key point is that UIKit does not constantly poll preferredStatusBarStyle. It checks when appearance needs to be updated.

A Full Working Example

swift
1import UIKit
2
3final class DetailsViewController: UIViewController {
4    override var preferredStatusBarStyle: UIStatusBarStyle {
5        .lightContent
6    }
7
8    override func viewDidLoad() {
9        super.viewDidLoad()
10        view.backgroundColor = .black
11    }
12
13    override func viewWillAppear(_ animated: Bool) {
14        super.viewWillAppear(animated)
15        setNeedsStatusBarAppearanceUpdate()
16    }
17}
18
19final class HostingNavigationController: UINavigationController {
20    override var childForStatusBarStyle: UIViewController? {
21        visibleViewController
22    }
23}

This setup covers the most common navigation-controller case.

Other Situations to Check

A few other things can interfere:

  • a modal controller presented over the top
  • a custom container that never forwards status bar questions
  • trying to use the old application-wide status bar APIs
  • assuming the root controller and visible controller are the same thing

On modern iOS, the container hierarchy matters a lot more than many older tutorials suggest.

Scene-based apps do not change this core rule. Even with newer lifecycle APIs, UIKit still asks the currently responsible controller hierarchy for the status bar style.

Common Pitfalls

  • Setting UIViewControllerBasedStatusBarAppearance incorrectly in Info.plist.
  • Overriding preferredStatusBarStyle in a child controller while the navigation controller actually owns the decision.
  • Forgetting to call setNeedsStatusBarAppearanceUpdate() when the desired style changes dynamically.
  • Debugging the visible controller while a presented controller is actually in charge.
  • Mixing old global status bar techniques with modern controller-based appearance rules.

Summary

  • If preferredStatusBarStyle is not called, check ownership before checking syntax.
  • Controller-based status bar appearance should be enabled in Info.plist.
  • Navigation and tab bar controllers often need to forward the decision to the active child.
  • Call setNeedsStatusBarAppearanceUpdate() when the style changes after presentation.
  • In most cases, the bug is really about controller hierarchy, not about the override itself.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.