I try to change some items of the main menu in my SwiftUI macOS app. I don't have macOS Catalyst yet, where the UIKit and UIMenuBuilder comes into play. I want to create my app for macOS versions below Catalyst as well.
I added an AppDelegate where I want to change the main menu by removing certain entries and add a key shortcut to the edit > delete command.
Everything works fine until I add a NavigationView to the view stack:
import Cocoa
import SwiftUI
class AppDelegate: NSObject, NSApplicationDelegate {
func applicationDidFinishLaunching(_ aNotification: Notification) {
let mainMenu = NSApplication.shared.mainMenu
// this works
mainMenu!.removeItem(mainMenu!.item(withTitle: "File")!)
mainMenu!.item(withTitle: "Help")!.isHidden = true
// the following lines have no effect
let key = String(utf16CodeUnits: [unichar(NSBackspaceCharacter)], count: 1) as String
let del = mainMenu!.item(withTitle: "Edit")!.submenu!.item(withTitle: "Delete")
del!.keyEquivalent = key
del!.keyEquivalentModifierMask = NSEvent.ModifierFlags.command
del!.action = #selector(foobar)
// no item is added to Edit menu
let newItem = NSMenuItem(title: "Foobar", action: #selector(foobar), keyEquivalent: "D")
mainMenu!.item(withTitle: "Edit")!.submenu!.addItem(newItem)
}
@objc func foobar() {
print("foobar")
}
}
@main
struct testApp: App {
#if os(macOS)
@NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
#endif
var body: some Scene {
WindowGroup {
NavigationView {
Text("hi")
}
.frame(width: 300, height: 200, alignment: .center)
}
}
}
When you remove the NavigationView in testApp and only Show Text("hi"), all commands from my AppDelegate work well.
However, when you have a NavigationView somewhere in your UI, the .removeItem
and .isHidden = true
still work, but the rest does not.
Why does having a NavigationView somewhere in your UI (it doesn't have to be the top one, can also be more layers between) enable me to add a key shortcut to a menu item? Is this a bug? If yes, is this a known bug? If no, why is it happening?
Should I build the main menu completely on my own instead of using the default one created by the app?