Skip to content

Instantly share code, notes, and snippets.

@chrsp
Last active January 28, 2022 21:13
Show Gist options
  • Save chrsp/941c0cfb0a343cce00adac12cd7d8f2e to your computer and use it in GitHub Desktop.
Save chrsp/941c0cfb0a343cce00adac12cd7d8f2e to your computer and use it in GitHub Desktop.
extension Reactive where Base == UIScreen {
@available(iOS 13.0, *)
func userInterfaceStyle() -> Observable<UIUserInterfaceStyle> {
let currentUserInterfaceStyle = UITraitCollection.current.userInterfaceStyle
let initial = Observable.just(currentUserInterfaceStyle)
let selector = #selector(UIScreen.traitCollectionDidChange(_:))
let following = self.base
.rx
.methodInvoked(selector)
.flatMap { (args) -> Observable<UIUserInterfaceStyle> in
return Observable.just(UITraitCollection.current.userInterfaceStyle)
}
return Observable.concat(initial, following)
}
}
@available(iOS 13.0, *)
private func observeUserInterfaceStyle() {
UIScreen.main.rx
.userInterfaceStyle()
.subscribe(onNext: { [weak self] userInterfaceStyle in
print("userInterfaceStyle changed to: \(userInterfaceStyle.description)")
self?.loadAppStyleSheet()
})
.disposed(by: disposeBag)
}
@gsbernstein
Copy link

Thank you! Very helpful when trying to observe the system setting while the window's overrideUserInterfaceStyle is set.

One idea is I think you could combine lines 10 and 11 to just map { _ in UITraitCollection.current.userInterfaceStyle }
Also you could use startWith(currentUserInterfaceStyle) instead of making a second observable and concatenating

If you don't want it to fire when irrelevant traits change, you could also add a filter on previous?.userInterfaceStyle != UITraitCollection.current.userInterfaceStyle (or map to userInterfaceStyle and then call distinctUntilChanged)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment