приложение не обновляется и traitCollectionDidChange не запускается, когда пользователь меняет внешний вид в настройках - PullRequest
1 голос
/ 04 марта 2020

В моем приложении я позволяю пользователю переопределить внешний вид, установленный на устройстве. Вот класс, который обрабатывает обновление пользовательского интерфейса, если они хотят переопределить общесистемный внешний вид:

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()
            })
        }
    }
}

Это работает - пользователь щелкает выключателем, а приложение меняет userInterfaceStyle. Проблема в том, что приложение не меняет внешний вид автоматически, когда пользователь изменяет внешний вид всей системы (установите светлый или темный режим в настройках), ТОЛЬКО когда они устанавливают его вручную.

Итак, я предполагаю, что мне нужно выполнить некоторую работу, когда пользователь изменяет ее в масштабе всей системы, и мне кажется, что мне нужно использовать traitCollectionDidChange. Проблема в том, что он не срабатывает, когда пользователь меняет внешний вид в настройках, ТОЛЬКО когда он установлен вручную в моем приложении. У меня есть этот код в viewController, чтобы проверить, что:

class ViewController: UIViewController, UIGestureRecognizerDelegate {

    // Lots of stuff

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

    // Lots more stuff
}

Когда я вручную переопределяю, он печатает «У нас есть изменение режима стиля». Когда я go захожу в настройки и переключаю общесистемный внешний вид, traitCollectionDidChange не срабатывает.

Клянусь, в какой-то момент это нормально работало, но я пытался исправить некоторые странные проблемы для в то время как теперь, когда я использую overrideUserInterfaceStyle и пережил много изменений кода.

Я думаю, что упускаю что-то очевидное Прежде чем я начал разрешать пользователю переопределять, приложение автоматически переключалось в фоновом режиме, когда внешний вид был изменен во всей системе без кода вообще. Теперь это не так и traitCollectionDidChange не срабатывает. Что я пропускаю или делаю неправильно? Рад предоставить больше кода, если это может помочь.

Спасибо!

1 Ответ

2 голосов
/ 05 марта 2020

Проблема в том, что вы переопределяете стиль пользовательского интерфейса, который приводит к тому, что любые системные изменения не распространяются на ваше окно. Вам нужно установить overrideUserInterfaceStyle на .unspecified, иначе система не будет вызывать методы traitCollectionDidChange в вашем стеке представлений при изменении.

В наших приложениях мы предлагаем пользователю три варианта: automati c, светлое и темное, где каждая опция просто устанавливает overrideUserInterfaceStyle на соответствующую опцию.

Кстати, вам не нужно вызывать layoutIfNeeded() на всех ваших подпредставлениях - установка overrideUserInterfaceStyle триггеров перерисовать автоматически.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...