How to detect dark mode in Yosemite to change the status bar menu icon

osx-yosemiteosx-yosemite-beta

The status bar app icon has to be changed when dark mode is enabled in Yosemite.
How to detect if dark mode has been enabled ? Is there any notification for the same ?

Is it better to display another image or change the alpha value of existing Image ?
Need inputs on which is the better way to go ??

Best Answer

You should make use of template images wherever possible because they allow your UI to automatically adapt to changes made by the system (at least when there's not a bug in the system... http://indiestack.com/2014/10/yosemites-dark-mode/). But in the case where you might use a custom view in the status bar and cannot take advantage of a template image, you can manually check for dark mode and adapt your UI accordingly.

You can check whether or not dark mode is enabled by retrieving a key from the user's global preferences, like this:

NSDictionary *dict = [[NSUserDefaults standardUserDefaults] persistentDomainForName:NSGlobalDomain];
id style = [dict objectForKey:@"AppleInterfaceStyle"];
BOOL darkModeOn = ( style && [style isKindOfClass:[NSString class]] && NSOrderedSame == [style caseInsensitiveCompare:@"dark"] );

At least for the first release of Yosemite, the key is not present when dark mode is disabled, but the key is present and returns the string value @"Dark" when dark mode is enabled. I added the case insensitive compare because I have seen preference keys change their case between system releases, and this adds a little insurance against that.

To monitor the current state of the setting, you register as an observer of a distributed notification (within an appropriate method), like this:

[[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(darkModeChanged:) name:@"AppleInterfaceThemeChangedNotification" object:nil];

And you create a method to act as the message selector for the notification, like this:

-(void)darkModeChanged:(NSNotification *)notif
{
    NSLog(@"Dark mode changed");
}
Related Topic