Search code examples
swiftosx-yosemitensstatusitem

How can I read the user selection for OS X menu bar in Xcode (Swift)


I'm creating an agent app for OS X in swift (only showing the app icon in the menu bar). I'm loading the icon for the app from the AppDelegate using:

 statusItem.image = NSImage(named: "BlackIcon")

and it works fine.

However, if the user has chosen to use the dark menu bar from the System Preferences -> General, the user won't see the icon as it's black.

enter image description here

So I need to display a different 'WhiteIcon' to the user if they have the option selected.

How can I check whether the user has this option active from my app?


Solution

  • It appears that you are trying to invert menulet icon color for dark mode. By default OSX handles darkmode and inverts the image color, however you need to specifically add [image setTemplate:YES] to have this work for you if it already doesnt.

    Objective-c:

    self.statusItem = [[NSStatusBar systemStatusBar]     
    statusItemWithLength:NSSquareStatusItemLength];
    NSImage *image = [NSImage imageNamed:@"statusItemIcon"];
    [image setTemplate:YES];
    [self.statusItem setImage:image];
    

    swift: (Originally answered by Zhi-Wei Cai at link below)

    var isDark = false
    
    func isDarkMode() {
      // Swift2
      // isDark = NSAppearance.currentAppearance().name.hasPrefix("NSAppearanceNameVibrantDark") 
    
      // Swift3+
      isDark = NSAppearance.current.name.rawValue.hasPrefix("NSAppearanceNameVibrantDark") 
    }
    
    override func drawRect(dirtyRect: NSRect) {
    super.drawRect(dirtyRect)
    isDarkMode()
    // Now use "isDark" to determine the drawing colour.
    if isDark {
        // ...
     } else {
        // ...
     }
    }
    

    This answer explains it in the detail: NSStatusItem change image for dark tint