Ios 应用程序没有';t更新和跟踪CollectionDidChange不';当用户在设置中更改外观时不会触发

Ios 应用程序没有';t更新和跟踪CollectionDidChange不';当用户在设置中更改外观时不会触发,ios,swift,ios-darkmode,uitraitcollection,Ios,Swift,Ios Darkmode,Uitraitcollection,在我的应用程序中,我允许用户覆盖设备上设置的外观。如果要覆盖系统范围的外观,下面是处理更新UI的类: class UserInterfaceStyleController { init() { self.handleUserInterfaceStyleChange() NotificationCenter.default.addObserver(self, selector: #selector(self.handleUserInterfaceStyleChange), nam

在我的应用程序中,我允许用户覆盖设备上设置的外观。如果要覆盖系统范围的外观,下面是处理更新UI的类:

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()
            })
        }
    }
}
这是可行的-用户翻转开关,应用程序更改用户界面样式。问题是,当用户更改系统范围的外观(在设置中设置亮或暗模式)时,应用程序不会自动更改外观,只有在用户手动设置时才会自动更改

因此,我假设当用户在系统范围内对其进行更改时,我需要做一些工作,而traitCollectionDidChange似乎是我需要使用的。问题是,当用户在“设置”中更改外观时,它不会启动,只有在“我的应用”中手动设置时才会启动。 我在viewController中有以下代码来测试:

class ViewController: UIViewController, UIGestureRecognizerDelegate {

    // Lots of stuff

    override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
        print("We have a style mode change")
    }

    // Lots more stuff
}
当我手动覆盖时,它会打印“我们有一个样式模式更改”。当我进入设置并切换系统范围的外观时,traitCollectionDidChange不会启动

我发誓我在某一点上工作得很好,但我已经尝试解决一些奇怪的问题有一段时间了,当时我使用overrideUserInterfaceStyle,经历了很多代码更改

我想我遗漏了一些明显的东西。在我开始允许用户覆盖之前,当外观在整个系统范围内更改时,应用程序会在后台自动切换,而没有任何代码。现在没有了,traitCollectionDidChange也没有启动。我错过了什么或做错了什么?如果可能的话,我们很乐意提供更多的代码


谢谢

问题在于您覆盖了用户界面样式,这会导致任何系统更改不会传播到您的窗口。您需要将
overrideUserInterfaceStyle
设置为
.unspecified
,否则系统不会在更改时调用视图堆栈中的
traitCollectionDidChange
方法

在我们的应用程序中,我们为用户提供了三个选项:自动、亮和暗,其中每个选项仅将
overrideUserInterfaceStyle
设置为适当的选项


顺便说一句,您不需要在所有子视图上调用
layoutifneed()
,设置
overrideeUserInterfaceStyle
会自动触发重画。

我的大多数视图都会自动重画,但由于某些原因,我有一些视图没有,我必须手动重画。我还没有完全弄清楚是什么原因造成的,这可能与没有出现在屏幕上以及其他一些我还没有完全确定的事情有关。