Home > Software design >  refresh NSMenuItem on click/open of NSStatusItem
refresh NSMenuItem on click/open of NSStatusItem

Time:07-01

I have the following extension where I have a NSMenuItem with it's state being either on or off:

extension AppDelegate {
    
    func createStatusBarItem() {
        let sBar = NSStatusBar.system
        
        // create status bar item in system status bar
        sBarItem = sBar.statusItem(withLength: NSStatusItem.squareLength)
        ...
        
        let sBarMenu = NSMenu(title: "Options")
        
        // assign menu to status bar item
        sBarItem.menu = sBarMenu
        
        let enableDisableMenuItem = NSMenuItem(title: "Enabled", action: #selector(toggleAdvancedMouseHandlingObjc), keyEquivalent: "e")
        enableDisableMenuItem.state = sHandler.isAdvancedMouseHandlingEnabled() ? NSControl.StateValue.on : NSControl.StateValue.off
        sBarMenu.addItem(enableDisableMenuItem)
        
        ...
    }
    
    @objc func toggleAdvancedMouseHandlingObjc() {
        if sHandler.isAdvancedMouseHandlingEnabled() {
            sHandler.disableAdvancedMouseHandling()
        } else {
            sHandler.enableAdvancedMouseHandling()
        }
    }
}

As soon as I want to change the state of the sHandler object I would also like to refer this change to the NSMenuItem and enable or disable the check mark depending on the state of NSHandler.

However it looks like the menu is being built only at first launch. How do I re-trigger the menu item in order to show or not show the check mark?

CodePudding user response:

Keep a reference to the created NSMenuItem in your app delegate and update its state (assuming you use the item only in a single menu).

class AppDelegate: NSApplicationDelegate {

    var fooMenuItem: NSMenuItem?

}

    func createStatusBarItem() {
        ...
        let enableDisableMenuItem = NSMenuItem(title: "Enabled", action: #selector(toggleAdvancedMouseHandlingObjc), keyEquivalent: "e")
        self.fooMenuItem = enableDisableMenuItem
        ...
    }

    @objc func toggleAdvancedMouseHandlingObjc() {
        if sHandler.isAdvancedMouseHandlingEnabled() {
            sHandler.disableAdvancedMouseHandling()
        } else {
            sHandler.enableAdvancedMouseHandling()
        }

        self.fooMenuItem.state = sHandler.isAdvancedMouseHandlingEnabled() ? NSControl.StateValue.on : NSControl.StateValue.off
    }
  • Related