Since the actual appearance object you usually get via effectiveAppearance
is a composite appearance, asking for its name directly probably isn't a reliable solution.
Asking for the currentAppearance
usually isn't a good idea, either, as a view may be explicitly set to light mode or you want to know whether a view is light or dark outside of a drawRect:
where you might get incorrect results after a mode switch.
The solution I came up with looks like this:
BOOL appearanceIsDark(NSAppearance * appearance)
{
if (@available(macOS 10.14, *)) {
NSAppearanceName basicAppearance = [appearance bestMatchFromAppearancesWithNames:@[
NSAppearanceNameAqua,
NSAppearanceNameDarkAqua
]];
return [basicAppearance isEqualToString:NSAppearanceNameDarkAqua];
} else {
return NO;
}
}
You would use it like appearanceIsDark(someView.effectiveAppearance)
since the appearance of a specific view may be different than that of another view if you explicitly set someView.appearance
.
You could also create a category on NSAppearance
and add a - (BOOL)isDark
method to get someView.effectiveAppearance.isDark
(better chose a name that is unlikely to be used by Apple in the future, e.g. by adding a vendor prefix).
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…