Let me explain the setup. The appdelegate creates a navigation controller and sets my ViewController as its rootViewController. Then a tabbarcontroller is created and this navigationcontroller is added to it. iOS 13 darkmode is ignored/opted out of by setting overrideUserInterfaceStyle
to light on tabbar object.
The viewController has a button. When pressing this button, it switches between dark mode and light mode. It changes the barStyle of navigationBar and tabBar to either dark or default depending on the isDark property. When I first tap the button to change the theme, the navigationBar changes style but the tabBar doesn't. However, you do any kind of UI update, like pulling up the app switcher, activating control center, changing background color, animating something etc, the tabBar instantly changes to what its style was set. This only happens on iOS 13 (I made sure traitColletion isn't changing). The same thing works perfectly on iOS 12 and below. If you update any content that's under the tabBar, it updates the style to what you set it to.
Here's the code on my viewController
class TestViewController: UIViewController
{
override var preferredStatusBarStyle: UIStatusBarStyle
{
return .default
}
var dark = true
override func viewDidLoad()
{
title = "ABCD"
view.backgroundColor = .white
super.viewDidLoad()
let button = UIButton()
button.setTitleColor(.systemTintBlue, for: .normal)
button.setTitle("Theme", for: .normal)
button.addTarget(self, action: #selector(buttonPress), for: .touchUpInside)
view.addSubview(button)
button.translatesAutoresizingMaskIntoConstraints = false
button.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
button.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
}
@objc func buttonPress()
{
if dark
{
// view.backgroundColor = .gray
tabBarController?.tabBar.barStyle = .black
navigationController?.navigationBar.barStyle = .black
dark = false
return
}
dark = true
tabBarController?.tabBar.barStyle = .default
navigationController?.navigationBar.barStyle = .default
// view.backgroundColor = .darkGray
}
}
Other observations
if you subclass UITabBarController and apply a certain style in viewDidLoad, updating the style later won't work, you'd then have to change UITabBarAppearance and apply a blur effect yourself. Or, you can set the style in viewDidAppear
If you subclass UITabBarController, override overrideUserInterfaceStyle to light, and change barStyle to default in viewDidLoad, the tabbar appears with a white blur and can be toggled between dark and light as you wish. But if you set dark barStyle, it'll appear with dark blur and can't be changed later
If you subclass UITabBarController, override overrideUserInterfaceStyle to dark, no matter what you set the barStyle to in viewDidLoad, the barStyle will always be dark and can't be changed
None of these stupid issues happens on iOS 12 or blow. Or this is a simulator bug. I don't have a physical iOS 13 device.