ダーク/ライトモードで自動的に機能しないUIセットアップの一部は、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
が変更された場合にのみトリガーする適切な関数は何ですか?
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()
}
}