如何检测 OS X 是否处于深色模式?

问题描述 投票:0回答:12

我的可可应用程序在新的 OS X“黑暗模式”下运行时必须更改其行为。

有没有办法检测OS X风格是否设置为该模式?

macos cocoa themes
12个回答
92
投票

不认为有可可的方法可以检测它,但是您可以使用

defaults read
来检查 OSX 是否处于黑暗模式。

defaults read -g AppleInterfaceStyle

返回

Dark
(深色模式)或返回域对不存在。

编辑:

正如 Ken Thomases 所说,你可以通过 NSUserDefaults 访问 .GlobalPreferences,所以

NSString *osxMode = [[NSUserDefaults standardUserDefaults] stringForKey:@"AppleInterfaceStyle"];

如果 osxMode 是

nil
则不是深色模式,但如果 osxMode 是
@"Dark"
则处于深色模式。


40
投票

Swift 2 -> 字符串(“暗”,“亮”)

let appearance = NSUserDefaults.standardUserDefaults().stringForKey("AppleInterfaceStyle") ?? "Light"

Swift 3 -> 枚举(深色、浅色)

enum InterfaceStyle : String {
   case Dark, Light

   init() {
      let type = UserDefaults.standard.string(forKey: "AppleInterfaceStyle") ?? "Light"
      self = InterfaceStyle(rawValue: type)!
    }
}

let currentStyle = InterfaceStyle()

21
投票

您可以使用

NSAppearanceCustomization
方法
effectiveAppearance
通过检查
darkAqua
来检测这一点。

Swift 4 示例:

extension NSView {
    var isDarkMode: Bool {
        if #available(OSX 10.14, *) {
            if effectiveAppearance.name == .darkAqua {
                return true
            }
        }
        return false
    }
}

15
投票

如果您不想处理枚举和 switch 语句,也可以将其包装在布尔值中:

/// True if the application is in dark mode, and false otherwise
var inDarkMode: Bool {
    let mode = UserDefaults.standard.string(forKey: "AppleInterfaceStyle")
    return mode == "Dark"
}

适用于 Swift 4.2


13
投票

要使用新的 macOS Catalina,您需要将

AppleInterfaceStyle
与引入的新值
AppleInterfaceStyleSwitchesAutomatically
结合起来。

这里有一些伪代码解释如何:

theme = light //default is light
if macOS_10.15
    if UserDefaults(AppleInterfaceStyleSwitchesAutomatically) == TRUE
        if UserDefaults(AppleInterfaceStyle) == NIL
            theme = dark // is nil, means it's dark and will switch in future to light
        else
            theme = light //means it's light and will switch in future to dark
        endif
    else
        if UserDefaults(AppleInterfaceStyle) == NIL
            theme = light
        else
            theme = dark
        endif
    endif
else if macOS_10.14
    if UserDefaults(AppleInterfaceStyle) == NIL
        theme = light
    else
        theme = dark
    endif
endif

您可以在此处查看 macOS 示例应用程序:https://github.com/ruiaureliano/macOS-Appearance

(免责声明:我是此示例应用程序的作者。)


12
投票

我会像这样检查所有黑暗的外观

extension NSView {

    var hasDarkAppearance: Bool {
        if #available(OSX 10.14, *) {
            switch effectiveAppearance.name {
            case .darkAqua, .vibrantDark, .accessibilityHighContrastDarkAqua, .accessibilityHighContrastVibrantDark:
                return true
            default:
                return false
            }
        } else {
            switch effectiveAppearance.name {
            case .vibrantDark:
                return true
            default:
                return false
            }
        }
    }
}

4
投票

这有效:

if #available(OSX 10.14, *) {
    inputTextView.textColor = (NSApp.effectiveAppearance.name == NSAppearance.Name.darkAqua ? NSColor.white : NSColor.black)
}

3
投票

这不是问题的完整答案,因为提问者没有说明他们的用例是什么。如果他们想要他们的应用程序具有完全不同的行为,则以下行为不起作用。但是,如果他们只想更改某些自定义视图的颜色,这是Apple 的祝福方式

要做的事情是停止使用绝对颜色并开始使用语义颜色。这意味着为资产目录中要使用的每种颜色定义一个“颜色集”。定义颜色集后,在检查器中将设备设置为“Mac”,将外观设置为“任何、浅色、深色”。然后,您将获得三个颜色井,“任何”适用于不支持深色模式的旧版操作系统,“浅色”和“深色”应该是明显的。

这是一个例子:

这定义了一种颜色,在深色模式下为白色,在浅色模式或旧操作系统上为黑色。

定义颜色集后,您可以在

draw(_ dirtyRect:)
中检索颜色,如下所示:

let strokeColour = NSColor(named: NSColor.Name("gridColour")) ?? NSColor.black

在上面,如果不存在颜色集来处理

NSColor(named:)
的可选类型,我默认为黑色。


2
投票

检查深色模式的唯一安全方法是使用以下方法:

let viewUsesDarkMode: Bool
if #available(OSX 10.14, *) {
    viewUsesDarkMode = view.effectiveAppearance.bestMatch(from: [.aqua, .darkAqua]) == .darkAqua
} else {
    viewUsesDarkMode = false
}

这是唯一适用于所有情况的解决方案。无论您是否具有混合外观的视图,或者是否允许应用程序使用与系统默认值不同的外观,或者是否将系统配置为使用高对比度外观。


2
投票

2020 | SWIFT 5.1:

方式1:

@Environment(\.colorScheme) var scheme

方式2:

主题更改时不会更新 swiftUI。需要实现视图更新的额外逻辑:

#available(OSX 10.14, *)
static private var isLight: Bool { NSApp.effectiveAppearance.name == NSAppearance.Name.aqua }

#available(OSX 10.14, *)
static private var isDark: Bool { NSApp.effectiveAppearance.name == NSAppearance.Name.darkAqua }


1
投票

看一下 NSAppearance.Name (用 Swift 语言) - 有多种变体:

.darkAqua

.accessibilityHighContrastDarkAqua

.accessibilityHighContrastVibrantDark


0
投票

这可以从 GlobalPreferences 文件中提取当前模式。

sw_vers

产品名称:macOS
产品版本:13.5.1
构建版本:22G90

if [[ $(defaults read ~/Library/Preferences/.GlobalPreferences.plist  AppleInterfaceStyle 2>/dev/null) = Dark ]]; then
    echo 'Dark'
else
    echo 'Light'
fi
© www.soinside.com 2019 - 2024. All rights reserved.