Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to remap macOS default keyboard shortcuts in a SwiftUI native app

I’m building a multiplatform app with SwiftUI for iOS, iPadOS and macOS. The macOS app will be a native app, rather than using Catalyst.

The app has a number of different data types which can be added, the principal of which is an Event type. I want to add these as a submenu in the File menu, with the new event action, the most commonly used, available as ⌘N.

That keyboard shortcut is currently mapped to the New Window built-in menu action. I’d like to keep that action but instead, remap its keyboard shortcut to ⌘⇧N.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

I can’t see how to do that, however.

Currently I have a command set defined as below (with an environment object that handles the display of, and navigation to, the relevant panels):

struct NewItemCommands: Commands {
    @EnvironmentObject private var appNavigation: AppNavigation

    var body: some Commands {
        CommandGroup(before: .newItem) {
            Menu("New") {
                Button("Event", action: appNavigation.newEvent)
                    .keyboardShortcut("N")
                Button("Genre", action: appNavigation.newGenre)
                Button("Publication", action: appNavigation.newPublication)
                Button("Venue", action: appNavigation.newVenue)
            }
            .disabled(appNavigation.isShowingModal)
        }
    }
}

This gives me the submenu I want, with the correct shortcut assigned to New > Event. However, the New Window’s default shortcut remains but never gets responded to:

Example of menu, as modified by the above code

Is there a way to remap that shortcut for New Window – or a way to create a new command with identical functionality that I can use to replace the default, with my own shortcut assigned?

>Solution :

You can use CommandGroup(replacing:) instead of CommandGroup(before:). Pass in .newItem to replace the "new window" menu item, then add your own implementation of it, with keyboardShortcut(...).

.commands {
    CommandGroup(replacing: .newItem) {
        Menu("New") {
            Button("Event", action: {...})
                .keyboardShortcut("N")
            Button("Genre", action: {...})
            Button("Publication", action: {...})
            Button("Venue", action: {...})
        }
        Button("New Window") {
            // get this with @Environment(\.openWindow) var openWindow
            // and give your WindowGroup some id
            openWindow(id: "Some ID")
        }.keyboardShortcut("N", modifiers: [.command, .shift])
    }
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading