Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to assign multiple key equivalents to a Menu Item in Cocoa (via IB or programmatically)?

Tags:

cocoa

Specifically, I want my "New" menu item to respond to both Cmd+N and Cmd+T since it will open a new document in a tab.* How can I do this either in Interface Builder or programmatically?

* I can explain the reasoning further if needed, but I'm hoping to avoid a discussion of the merits and rather focus on how to do it, not why to do it.

like image 588
Lytol Avatar asked Oct 23 '10 20:10

Lytol


2 Answers

Make a second one (easiest way being to duplicate it) and set it as hidden. It won't show up when the user pulls open the menu, but as long as it's enabled, its key equivalents should still be in effect.

like image 153
Peter Hosey Avatar answered Sep 23 '22 08:09

Peter Hosey


enter image description here

A simple way to have two or more Key Equivalents for an action is to duplicate the NSMenuItem and add a special Tag for these "alternatives" menu items.

Then set the AppDelegate the delegate (NSMenuDelegate) of the corresponding enclosing NSMenu (where the inner items need the visibility to be updated).

Hidden menu items (or items with a hidden superitem) do not appear in a menu and do not participate in command key matching.

When the NSMenu open, hides this alternates NSMenuItem, when it close, display them.

Example in Swift 3:

class AppDelegate: NSObject, NSApplicationDelegate, NSMenuDelegate {

    func applicationDidFinishLaunching(_ aNotification: Notification) {
        NSApp.mainMenu?.item(withTitle: "View")?.submenu?.item(withTitle: "Zoom")?.submenu?.delegate = self
    }

    func toggleVisibility(_ visible: Bool, ofAlternatesKeyEquivalentsItems items: [NSMenuItem]) {
        for item in items.filter({ $0.tag == 2 }) {
            item.isHidden = !visible
        }
    }

    func menuWillOpen(_ menu: NSMenu) {
        if menu.title == "Zoom" {
            toggleVisibility(false, ofAlternatesKeyEquivalentsItems: menu.items)
        }
    }

    func menuDidClose(_ menu: NSMenu) {
        if menu.title == "Zoom" {
            toggleVisibility(true, ofAlternatesKeyEquivalentsItems: menu.items)
        }
    }
}
like image 35
Atika Avatar answered Sep 21 '22 08:09

Atika