MenuBar Items in SwiftUI

Before SwiftUI you would easily add, change or remove menuBarItems from your app Storyboard.

Screen Shot 2021 10 31 at 1 14 34 PM

With the transition to SwiftUI however, there’s no longer a StoryBoard file to edit… So, what now?

After the initial surprise, and having spent a few hours reading documentation… It’s actually a very straightforward three step process:

1. In your @main add “.commands” after WindowGroup 

WindowGroup {

            […]

           

        }.commands {

            

           //Here well add the MenuBarItems

            

        }

2. Then you have a couple choices: you can replace existing CommandGroups (like File-> New), enhance them with more options, or create a new MenuBar groups altogether. 

First, lets look at how you would create new MenuItems:

CommandMenu(“New menu”) {

    Button(“Some message”) {

        print(“Hello World!”)

    }.keyboardShortcut(d”)

 

    Button(“Second message”) {

        print(“Hello World2!”)

    }

 

    Picker(selection: $selection, label: Text(Selection”)) {

        Text(“Option 1”).tag(1)

        Text(“Option 2”).tag(2)

        Text(“Option 3”).tag(3)

    }

}

Yes, you can even create a picker!

But wait, if instead you’d like to replace or add to an existing menu:

CommandGroup(before: CommandGroupPlacement.newItem) {

        Button(“Something”) {

           //

        }

    }

 

    CommandGroup(replacingCommandGroupPlacement.newItem) {

        Button(“Something”) {

            // 

        }

    }

 

    CommandGroup(afterCommandGroupPlacement.newItem) {

        Button(Something”) {

           //

        }

}

 

Finally, what about cases where you’d like to trigger complex actions from a MenuBarItem? Well, you can create a SwiftUI class for it. 

Here’s how you would use the classes in the .commands section:

}.commands {

            //Check if we’re in task menu

            NewItem(ccd: ccd, viewContext: persistenceController.container.viewContext)

            DeleteItem(ccd: ccd, viewContext: persistenceController.container.viewContext)

            PinElement(ccd: ccd, viewContext: persistenceController.container.viewContext)

            Help()

            

        }

And here’s the contents of one of them for reference, in this case replacing the help menu with my custom buttons:

 

import SwiftUI

 

struct Help: Commands {

    var body: some Commands {

        CommandGroup(replacing: .help, addition: {

            Button(“Help”){

                let helpLink = “http://bluelemonbits.com”

                NSWorkspace.shared.open(URL(string: helpLink)!)

            }

            Button(“Contact us”){

                let service = NSSharingService(named: NSSharingService.Name.composeEmail)!

                service.recipients = [x@x.com”]

                service.subject = “Feedback \(arc4random() % 100000)

                service.perform(withItems: [” \nFeedback: \n”])

                

            }

        })

    }

}

 

Hope it helps! Questions/feedback? I’m @MarcMasVi

Until next time, 

 

Marc

 

PS: Some related articles on this very topic