我的cocoa app在新的OS X"黑暗模式"中运行时必须改变其行为。
有没有办法检测OS X样式是否设置为此模式?
答案 0 :(得分:53)
不要认为还有可靠的方法来检测它,但是你可以使用defaults read
来检查OSX是否处于黑暗模式。
defaults read -g AppleInterfaceStyle
返回Dark
(暗模式)或返回域对不存在。
修改强>
正如Ken Thomases所说,您可以通过NSUserDefaults访问.GlobalPreferences,所以
NSString *osxMode = [[NSUserDefaults standardUserDefaults] stringForKey:@"AppleInterfaceStyle"];
如果osxMode是nil
,那么它不是暗模式,但如果osxMode是@"Dark"
则它处于黑暗模式。
答案 1 :(得分:33)
Swift 2 - >字符串(" Dark"," Light")
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()
答案 2 :(得分:8)
您可以使用NSAppearanceCustomization
方法effectiveAppearance
通过检查darkAqua
来检测到这一点。
Swift 4示例:
extension NSView {
var isDarkMode: Bool {
if #available(OSX 10.14, *) {
if effectiveAppearance.name == .darkAqua {
return true
}
}
return false
}
}
答案 3 :(得分:6)
如果您不想处理枚举和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
上运行答案 4 :(得分:2)
要使用新的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。
干杯?
我是@OlaBrothers的Rui Aureliano,iOS和macOS工程师。 http://sipapp.io
的制造商答案 5 :(得分:2)
我会像这样检查所有深色外观
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
}
}
}
}
答案 6 :(得分:1)
看看NSAppearance.Name(用Swift来说)- 有变种:
.darkAqua
.accessibilityHighContrastDarkAqua
.accessibilityHighContrastVibrantDark
答案 7 :(得分:1)
2020年| SWIFT 5.1:
由于某种原因不能实时更新,但仍可以按需运行(可能在另一个地方出现问题,与该代码无关):
检查浅色主题:
#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 }
答案 8 :(得分:1)
接受的答案不正确。它告诉您系统偏好设置是否设置为暗,而不是当前应用程序的外观是否为暗。您可以通过以下方法进行测试:将系统外观设置为浅色,然后在Xcode中运行应用程序,然后按菜单>调试>查看调试>外观>黑暗。该应用程序将处于黑暗模式,但接受的答案中的方法将声称它不是。
这给出了正确的结果:
NSString *appearanceName = [[NSAppearance currentAppearance] name];
bool isDark = [appearanceName containsString:@"Dark"];
答案 9 :(得分:0)
这项工作
if #available(OSX 10.14, *) {
inputTextView.textColor = (NSApp.effectiveAppearance.name == NSAppearance.Name.darkAqua ? NSColor.white : NSColor.black)
}
答案 10 :(得分:0)
这不是问题的完整答案,因为发问者没有说出他们的用例是什么。如果他们想要其应用程序完全不同的行为,则以下行为不起作用。但是,如果他们只想更改某些自定义视图的颜色,则为the Apple blessed way。
要做的是停止使用绝对颜色,开始使用语义颜色。这意味着为您要在资产目录中使用的每种颜色定义一个“颜色集”。定义颜色设置后,在检查器中将设备设置为“ Mac”,将外观设置为“任何,浅,深”。然后,您将获得三个颜色范围,“ any”用于不支持深色模式的旧版操作系统,“ light”和“ dark”应该很明显。
这里是一个例子:
这定义了一种颜色,在深色模式下为白色,在浅色模式下或在旧版操作系统上为黑色。
定义了颜色集后,您可以在merge
中检索颜色,如下所示:
draw(_ dirtyRect:)
在上面,如果不存在用于处理可选类型let strokeColour = NSColor(named: NSColor.Name("gridColour")) ?? NSColor.black
的颜色集,则默认为黑色。