Omr
Omr

Reputation: 99

Reloading tab bar appearance

I am trying to reload the tab bar after the user changes the appearance of the app from light to dark mode and vice versa. I am able to update everything in the app except the tab bar. I don't want to force the user to close the app.

Upvotes: 6

Views: 2539

Answers (4)

Leon
Leon

Reputation: 3726

I would say that none of the answers here are correct (at time of writing). When assigning a colour to a view you simply need to make sure a dark mode colour is set and the system will automatically update it when the user changes mode.

Two main options for this:

  1. Use an asset catalog and make sure Appearances is set to 'Any, Dark', set both colours and assign it to the tab bar:

enter image description here

tabBar.backgroundColor = UIColor(named: "tabBarBackground")

  1. Or you can programmatically set a dark mode colour:

tabBar.backgroundColor = UIColor.clear.withDarkModeColor(.black)

Upvotes: 2

jlagrone
jlagrone

Reputation: 86

With iOS 13 you can override traitCollectionDidChange(_:) in UITabBarController to make changes. See documentation.

Example:

class TabBarControllerViewController: UITabBarController {

    ...

    override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
        self.tabBar.barTintColor = UIColor.red
        self.tabBar.unselectedItemTintColor = UIColor.darkGray
        self.tabBar.tintColor = UIColor.white
  }
}

Upvotes: 5

pacification
pacification

Reputation: 6018

If you try to look at docs about UIAppearance, you'll see the note:

iOS applies appearance changes when a view enters a window, it doesn’t change the appearance of a view that’s already in a window. To change the appearance of a view that’s currently in a window, remove the view from the view hierarchy and then put it back.

Based on this note you can change appearance with a little trick by remove and immediately set back the most top view in the hierarchy after applying changes to appearance:

guard let currentView = (UIApplication.shared.delegate as? AppDelegate)?.window?.rootViewController?.view,
    let superview = currentView.superview else { return }

UITabBar.appearance().tintColor = .green

currentView.removeFromSuperview()
superview.addSubview(currentView)

Upvotes: 7

user3596335
user3596335

Reputation:

You can just set the color of your tabBar using the tabBar.backgroundColor-property:

self?.tabBar.backgroundColor

Please make sure you are updating the background color on the main thread.

DispatchQueue.main.async { [weak self] in
   self?.tabBar.backgroundColor = newAppearanceColor
}

Upvotes: -1

Related Questions