Как обнаружить изменение режима Light \ Dark в iOS 13? - PullRequest
2 голосов
/ 19 сентября 2019

Некоторые настройки пользовательского интерфейса, не работающие автоматически в режиме Dark / Light, изменяются на UIColor.Например shadow в слое.Поскольку мне нужно удалять и отбрасывать тени в темном и светлом режимах, мне нужно куда-то поставить функцию updateShadowIfNeeded().Я знаю, как определить, какой сейчас режим:

func dropShadowIfNeeded() {
    switch traitCollection.userInterfaceStyle {
    case .dark: removeShadow()
    case .light: dropShadowIfNotDroppedYet()
    default: assertionFailure("Unknown userInterfaceStyle")
    }
}

Теперь я помещаю функцию в layoutSubviews, так как она вызывается при каждом изменении внешнего вида:

override func layoutSubviews() {
    super.layoutSubviews()
    dropShadowIfNeeded()
}

Ноэта функция вызывается A LOT .Какую функцию следует запускать, только если userInterfaceStyle изменилось?

Ответы [ 3 ]

1 голос
/ 19 сентября 2019

Я нашел ответ на WWDC 2019 - Сессия 214 около 23: 30.

Как я и ожидал, эта функция часто вызывается, в том числе и при изменении цвета.Наряду со многими другими функциями для ViewController и presentationController.Но есть специальная функция, разработанная для этого, которая имеет похожую подпись во всех View представителях.

Посмотрите на это изображение из этого сеанса:

WWDC 2019 - Session 214

Серый: вызов, но не подходит для моей проблемы, Зеленый: предназначен для этого

Поэтому я должен вызвать его и проверить его внутри этой функции:

override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
    super.traitCollectionDidChange(previousTraitCollection)

    if traitCollection.hasDifferentColorAppearance(comparedTo: previousTraitCollection) {
        dropShadowIfNeeded()
    }
}

Это гарантирует, что вызов будет вызываться только один раз за изменение.

1 голос
/ 19 сентября 2019

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

override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
    super.traitCollectionDidChange(previousTraitCollection)

    guard previousTraitCollection?.userInterfaceStyle != traitCollection.userInterfaceStyle else {
        return
    }
    dropShadowIfNeeded()
}
0 голосов
/ 25 сентября 2019

С помощью RxSwift и ObjectiveC вы можете достичь этого без наследования

вот инкапсулированная версия:

import UIKit
import RxSwift
import RxCocoa

enum SystemTheme {
    static func get(on view: UIView) -> UIUserInterfaceStyle {
        view.traitCollection.userInterfaceStyle
    }

    static func observe(on view: UIView) -> Observable<UIUserInterfaceStyle> {
        view.rx.methodInvoked(#selector(UIView.traitCollectionDidChange(_:)))
            .map { _ in SystemTheme.get(on: view) }
            .distinctUntilChanged()
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...