【问题标题】:How to detect switch between macOS default & dark mode using Swift 3如何使用 Swift 3 检测 macOS 默认和暗模式之间的切换
【发布时间】:2016-12-27 04:42:47
【问题描述】:

我想在用户从默认模式切换到暗模式时更改我的状态栏应用程序图标,反之亦然(使用 Swift 3)。这是我目前所拥有的:

func applicationDidFinishLaunching(_ aNotification: Notification) {
    DistributedNotificationCenter.default().addObserver(self, selector: #selector(darkModeChanged(sender:)), name: "AppleInterfaceThemeChangedNotification", object: nil)
}

...

func darkModeChanged(sender: NSNotification) {
    print("mode changed")
}

不幸的是,它不起作用。我做错了什么?

【问题讨论】:

    标签: swift selector nsnotificationcenter observers nsdistributednotification


    【解决方案1】:

    我成功地使用了这个 Swift 3 语法:

    DistributedNotificationCenter.default.addObserver(self, selector: #selector(interfaceModeChanged(sender:)), name: NSNotification.Name(rawValue: "AppleInterfaceThemeChangedNotification"), object: nil)
    
    func interfaceModeChanged(sender: NSNotification) {
      ...
    }
    

    【讨论】:

    • 非常感谢,很好的解决方案! :)
    • 它在 Mac 催化剂中不起作用。有什么方法可以在 Mac 催化剂中实现这一点?
    • 我需要objective-c语法。
    【解决方案2】:

    Swift 5、Xcode 10.2.1、macOS 10.14.4

    好东西。 @Jeffrey 的回答是我的两分钱:

    extension Notification.Name {
        static let AppleInterfaceThemeChangedNotification = Notification.Name("AppleInterfaceThemeChangedNotification")
    }
    

    所以可以(而不是rawValue):

    func listenToInterfaceChangesNotification() {
        DistributedNotificationCenter.default.addObserver(
            self,
            selector: #selector(interfaceModeChanged),
            name: .AppleInterfaceThemeChangedNotification,
            object: nil
        )
    }
    

    记住@objc属性:

    @objc func interfaceModeChanged() {
        // Do stuff.
    }
    

    【讨论】:

      【解决方案3】:

      如果您只需要更新黑暗模式的图标图像,您可以通过创建自动更新的动态图像来执行此操作而无需通知。

      来自苹果的documentation

      要创建动态绘制其内容的图像,请使用init(size:flipped:drawingHandler:) 方法通过自定义绘图处理程序块初始化您的图像。每当系统外观发生变化时,AppKit 都会调用您的处理程序块,让您有机会使用新外观重绘图像。

      【讨论】:

        【解决方案4】:

        所以,还有我的小补充:

        enum InterfaceStyle: String {
            case Light
            case Dark
            case Unspecified
        }
        
        extension Notification.Name {
            static let AppleInterfaceThemeChangedNotification = Notification.Name("AppleInterfaceThemeChangedNotification")
        }
        
        extension NSViewController {
            var interfaceStyle: InterfaceStyle {
                let type = UserDefaults.standard.string(forKey: "AppleInterfaceStyle") ?? "Unspecified"
                return InterfaceStyle(rawValue: type) ?? InterfaceStyle.Unspecified
            }
        }
        

        在 NSViewController 中的某处:

                DistributedNotificationCenter.default.addObserver(forName: .AppleInterfaceThemeChangedNotification,
                                                                  object: nil, queue: OperationQueue.main) {
                    [weak weakSelf = self] (notification) in                // add an observer for a change in interface style
                    weakSelf?.setAppearance(toStyle: weakSelf!.interfaceStyle)
                }
        

        setAppearance 对风格变化的反应。

        【讨论】:

          猜你喜欢
          • 2021-12-09
          • 2021-09-12
          • 2021-10-14
          • 2021-05-30
          • 2019-01-11
          • 1970-01-01
          • 2020-08-24
          • 2020-10-01
          • 1970-01-01
          相关资源
          最近更新 更多