当 SwiftUI 更新窗口正文时,当前的建议对我来说失败了。
解决方案:
使用 KVO 并观察 NSApp 以了解 \.mainMenu 上的更改。在 SwiftUI 轮到你之后,你可以删除任何你想要的东西。
@objc
class AppDelegate: NSObject, NSApplicationDelegate {
var token: NSKeyValueObservation?
func applicationDidFinishLaunching(_ notification: Notification) {
// Remove a single menu
if let m = NSApp.mainMenu?.item(withTitle: "Edit") {
NSApp.mainMenu?.removeItem(m)
}
// Remove Multiple Menus
["Edit", "View", "Help", "Window"].forEach { name in
NSApp.mainMenu?.item(withTitle: name).map { NSApp.mainMenu?.removeItem($0) }
}
// Must remove after every time SwiftUI re adds
token = NSApp.observe(\.mainMenu, options: .new) { (app, change) in
["Edit", "View", "Help", "Window"].forEach { name in
NSApp.mainMenu?.item(withTitle: name).map { NSApp.mainMenu?.removeItem($0) }
}
// Remove a single menu
guard let menu = app.mainMenu?.item(withTitle: "Edit") else { return }
app.mainMenu?.removeItem(menu)
}
}
}
struct MarblesApp: App {
@NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some View {
//...
}
}
想法:
SwiftUI 要么存在错误,要么他们真的不希望您删除 NSApp.mainMenu 中的顶级菜单。 SwiftUI 似乎重置了整个菜单,目前无法覆盖或自定义大多数细节(Xcode 13.4.1)。 CommandGroup(replacing: .textEditing) { }-esque 命令不允许您删除或清除整个菜单。分配一个新的NSApp.mainMenu 只会在 SwiftUI 需要时被破坏,即使你没有指定任何命令。
这似乎是一个非常脆弱的解决方案。应该有办法告诉 SwiftUI 不要触摸NSApp.mainMenu 或启用更多自定义。或者 SwiftUI 似乎应该检查它是否拥有上一个菜单(菜单项是 SwiftUI.AppKitMainMenuItem)。或者我错过了他们提供的一些工具。希望这在 WWDC 测试版中得到修复?
(在带有 Swift 5 的 Xcode 13.4.1 中,针对不带 Catalyst 的 macOS 12.3。)