iOS Dark Mode UINavigationBar not updating background color

I figured that I'd get the support for Dark Mode out of the box with UINavigationBar since I use the default opaque color scheme.


I've noticed that when I switch the dark mode setting to ON either from environment in xcode, or command center with the screen brightness shortcut, my UINavigationController navbar background stays white but the title text color does change to the dark mode title color, white. White text on white background. I verified that the label is still there and still white using the Debug View Heirarchy within xcode.


Sometimes, when I rotate then to landscape, the background will update to dark mode color. It isn't consistent. Same goes for the inverse, changing dark to light mode. Dark text on Dark background color.


From a user's perspective, after a swipe-kill and relaunch, the color matches the themes in all orientations and navigation bars.


I have my nav bars set to opaque from storyboard. Is there something else I'm missing that needs to be done? I didn't see anything in the adopting dark mode video from WWDC 19.



Updated Aug 26, 2019

I'm still seeing this behavior in dev beta 8. Created a bug report--hopefully this gets fixed. FB7134275


Is anyone else affected by this? Basic app layout similar to either Phone or Clock app.


UITabBarController (opaque bottom bar) -

UINavigationController (opaque top bar) -

UIViewController

UINavigationController (opaque top bar) -

UITableViewController


This is really non-functional because the title color is changed, but the bar color is not changing.


Update Jan 6, 2020

iOS 13.3 no longer seems to have this issue. I'm not sure in which earlier update this was addressed.

Accepted Reply

I have this issue too. Very frustrating. I've ended up creating a subclass af UINavigationController that sets the barTintColoer whenever the trait collection changes. It's not pretty, but does the job until Apple fixes it at their end.


class DarkModeAwareNavigationController: UINavigationController {

  override init(rootViewController: UIViewController) {
       super.init(rootViewController: rootViewController)
       self.updateBarTintColor()
  }

  required init?(coder aDecoder: NSCoder) {
       super.init(coder: aDecoder)
       self.updateBarTintColor()
  }

  override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
       super.traitCollectionDidChange(previousTraitCollection)
       self.updateBarTintColor()
  }

  private func updateBarTintColor() {
       if #available(iOS 13.0, *) {
            self.navigationBar.barTintColor = UITraitCollection.current.userInterfaceStyle == .dark ? .black : .white
  }
  }
}

Replies

I am having this issue as well. Everything changes when switiching from Dark Mode to Light Mode or vice versa except for the UINavigationBar. This issue occurs whether I am using a system color or if I am using a custom color with different shades for light and dark mode.


Like edorphy stated as well, if I change the view the navigation bar color will update to the correct color scheme but it will not update if I leave it on the same view and change between the two appearance modes.

Same issue here. Did you figure out a way to work around it?

There is actually a solution: If you add the Color as a `Color Set` via an Asset Catalog and then load this color via `UIColor(named:bundle:compatibleWith:)` func the color will be updated automatically.

Same exact issue.


The proposed resolution doesn't really work for me since I need to keep existing support for a backwards-compatible dark mode.

in the app delegate i made the app detect if darkMode is enabled, if it is i set the nav controller to be dark and visa versa

I have this issue too. Very frustrating. I've ended up creating a subclass af UINavigationController that sets the barTintColoer whenever the trait collection changes. It's not pretty, but does the job until Apple fixes it at their end.


class DarkModeAwareNavigationController: UINavigationController {

  override init(rootViewController: UIViewController) {
       super.init(rootViewController: rootViewController)
       self.updateBarTintColor()
  }

  required init?(coder aDecoder: NSCoder) {
       super.init(coder: aDecoder)
       self.updateBarTintColor()
  }

  override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
       super.traitCollectionDidChange(previousTraitCollection)
       self.updateBarTintColor()
  }

  private func updateBarTintColor() {
       if #available(iOS 13.0, *) {
            self.navigationBar.barTintColor = UITraitCollection.current.userInterfaceStyle == .dark ? .black : .white
  }
  }
}

Could you please post a solution for this? I've been looking for this..

This looks good for earlier releases. I don't know when I quit experiencing the issue, but as of iOS 13.3 I no longer see this.