user10802841
user10802841

Reputation: 67

How do I hide default CommandMenu entries in SwiftUI on macOS?

I am trying to delete the default menu items of my SwiftUI App, like described in this question by JoeBayLD (How do I hide default CommandMenu in SwiftUI on macOS?)

None of the answers there seem to work and neither did I find another solution. Any idea how to delete the default items?

Screenshot of menu bar

Upvotes: 1

Views: 794

Answers (3)

Vëx
Vëx

Reputation: 1376

To achieve removal of all default menu commands in order to add your own, you can use the following Scene modifier:

var body: some Scene {
   WindowGroup {
       MainWindow()
   }
   .commandsReplaced(content: {
       CommandMenu("Your_custom_menu") {
           Button {
               //some action
           } label: {
               Text(verbatim: "Custom action...")
           }
       })
   })
}

Official documentation on .commandsReplaced modifier.

Please note this modifier isn't available in all OS versions, and it may affect built-in command of your product (first one after default Apple OS menu).

Here are the minimums:

  • iOS 16.0+
  • iPadOS 16.0+
  • Mac Catalyst 16.0+
  • macOS 13.0+
  • visionOS 1.0+

Upvotes: 0

kittonian
kittonian

Reputation: 1431

If you want to remove all of the default menu items you can use the .commandsRemoved() modifier on your WindowGroup

Upvotes: 1

EmilioPelaez
EmilioPelaez

Reputation: 19912

I recently went through this and was unable to remove the sections (File, Edit, View), so I settled with removing some of the items that didn't apply to my app.

This is what I ended up with. It doesn't include .newItem because I replaced it, but if you don't need it I would suggest adding it, otherwise users can create more windows of your app.

struct EmptyCommands: Commands {
    var body: some Commands {
        CommandGroup(replacing: .saveItem) {
            EmptyView()
        }
        CommandGroup(replacing: .printItem) {
            EmptyView()
        }
        CommandGroup(replacing: .undoRedo) {
            EmptyView()
        }
        CommandGroup(replacing: .pasteboard) {
            EmptyView()
        }
    }
}

Unfortunately, even if you remove all the items in a group, the group stays, even if empty.

There's probably a way of doing this using AppKit, but I didn't dig deeper because my solution was good enough for me.

Upvotes: 3

Related Questions