Skip to content

Instantly share code, notes, and snippets.

@DivineDominion
Created December 19, 2018 11:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DivineDominion/b648ccfd1021bb1acdc93a52089e70d7 to your computer and use it in GitHub Desktop.
Save DivineDominion/b648ccfd1021bb1acdc93a52089e70d7 to your computer and use it in GitHub Desktop.
`NSAppearance` change notification when you cannot use `NSApp.effectiveAppearance` which is available for macOS 10.14+ only
import Cocoa
import RxSwift
import RxCocoa
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
@IBOutlet weak var window: NSWindow!
let disposeBag = DisposeBag()
func applicationDidFinishLaunching(_ aNotification: Notification) {
setUpAppearanceChangeNotifications()
consumeAppearanceChangeNotificiations()
}
fileprivate func setUpAppearanceChangeNotifications() {
window!.contentView!.rx
.isDarkMode
.startWith(NSAppearance.current.isDarkMode)
.subscribe { isDarkMode in
NotificationCenter.default.post(
name: NSView.darkModeDidChange,
object: nil,
userInfo: [NSAppearance.isDarkModeKey : isDarkMode])
}.disposed(by: disposeBag)
}
fileprivate func consumeAppearanceChangeNotificiations() {
let darkModeChange = NotificationCenter.default.rx
.notification(NSView.darkModeDidChange)
.map { $0.userInfo?[NSAppearance.isDarkModeKey] as? Bool }
.filter { $0 != nil }.map { $0! }
darkModeChange.debug("Dark Mode Change Signal").subscribe().disposed(by: disposeBag)
}
}
import Cocoa
extension NSView {
static var darkModeDidChange: Notification.Name { return .init(rawValue: "NSAppearance did change") }
}
extension NSAppearance {
static var isDarkModeKey: String { return "isDarkMode" }
}
import Cocoa
// Adapted from https://indiestack.com/2018/10/supporting-dark-mode-checking-appearances/
extension NSAppearance {
public var isDarkMode: Bool {
if #available(macOS 10.14, *) {
if self.bestMatch(from: [.darkAqua, .aqua]) == .darkAqua {
return true
} else {
return false
}
} else {
return false
}
}
}
import Cocoa
import RxSwift
extension Reactive where Base: NSView {
var effectiveAppearance: ControlEvent<NSAppearance> {
let source = base.rx
.observe(NSAppearance.self, "effectiveAppearance", options: [.new])
.map { $0 ?? NSAppearance.current }
return ControlEvent(event: source)
}
var isDarkMode: ControlEvent<Bool> {
return base.rx.effectiveAppearance
.map { $0.isDarkMode }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment