In my app I allow the user to override the appearance that is set on the device. Here's the class that handles updating the UI if they want to override the system-wide appearance:
class UserInterfaceStyleController {
init() {
self.handleUserInterfaceStyleChange()
NotificationCenter.default.addObserver(self, selector: #selector(self.handleUserInterfaceStyleChange), name: Notification.Name(OMGNotification.changeBizzaroMode.rawValue), object: nil)
}
@objc func handleUserInterfaceStyleChange() {
if #available(iOS 13.0, *) {
let windows = UIApplication.shared.windows
for window in windows {
if UIScreen.main.traitCollection.userInterfaceStyle == .light {
if UserDefaults.standard.bizzaroMode {
window.overrideUserInterfaceStyle = .dark
} else {
window.overrideUserInterfaceStyle = .light
}
}
if UIScreen.main.traitCollection.userInterfaceStyle == .dark {
if UserDefaults.standard.bizzaroMode {
window.overrideUserInterfaceStyle = .light
} else {
window.overrideUserInterfaceStyle = .dark
}
}
window.subviews.forEach({ view in
view.layoutIfNeeded()
})
}
}
}
This works - the user flips the switch and the app changes the userInterfaceStyle. The problem is the app doesn't change appearance automatically when the user changes the system-wide appearance (set light or dark mode in settings), ONLY when they set it manually.
So I'm assuming I need to do some work when the user changes it system-wide, and traitCollectionDidChange seems to be what I need to use. Problem is it doesn't fire when the user changes the appearance in settings, ONLY when it's manually set in my app. I've got this code in a viewController to test that:
class ViewController: UIViewController, UIGestureRecognizerDelegate {
// Lots of stuff
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
print("We have a style mode change")
}
// Lots more stuff
}
When I manually override, it prints, "We have a style mode change". When I go into settings and switch the system-wide appearance traitCollectionDidChange doesn't fire.
I swear I had this working fine at one point, but I've been trying to fix some weird issues for a while now when I use overrideUserInterfaceStyle and have burned through a lot of code changes.
I think I'm missing something obvious. Before I started allowing the user to override, the app switched automatically in the background when the appearance was changed system-wide with no code at all. Now it doesn't and traitCollectionDidChange doesn't fire. What am I missing or doing wrong? Happy to provide more code if it could help.
Thanks!