SwiftUI -- 使用自定义内容覆盖AppDelegate:
@main
struct PixieApp: App {
@NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
///........
}
appDelegate的代码:
final class AppDelegate: NSObject, NSApplicationDelegate {
func applicationWillUpdate(_ notification: Notification) {
DispatchQueue.main.async {
if let menu = NSApplication.shared.mainMenu {
menu.items.removeFirst{ $0.title == "Edit" }
menu.items.removeFirst{ $0.title == "File" }
menu.items.removeFirst{ $0.title == "Window" }
menu.items.removeFirst{ $0.title == "View" }
}
}
}
}
结果:
在SwiftUI添加更多关于菜单的支持之前,我认为你需要担心SwiftUI在更新window.body
时重置NSApp.mainMenu
。我没有尝试过所有调整mainMenu
的方法,但是在我尝试的方法中,缺陷在于SwiftUI似乎没有检查它是否最后设置了NSApp.mainMenu
或者是否有其他东西设置了它。
因此,无论你如何管理菜单,在SwiftUI更新之后进行更新。
使用KVO并监视NSApp的主菜单更改。然后使用xib进行更改,或重新设置整个菜单,或编辑SwiftUI的菜单。
示例:
@objc
class AppDelegate: NSObject, NSApplicationDelegate {
var token: NSKeyValueObservation?
func applicationDidFinishLaunching(_ notification: Notification) {
// Adjust a menu initially
if let m = NSApp.mainMenu?.item(withTitle: "Edit") {
NSApp.mainMenu?.removeItem(m)
}
// Must refresh after every time SwiftUI re adds
token = NSApp.observe(\.mainMenu, options: .new) { (app, change) in
// Refresh your changes
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 {
//...
}
}
这似乎在使用Swift 5针对macOS 12.3的Xcode 13.4.1中有效。
希望苹果很快添加更多控制选项。 Catalyst似乎有其他选项。 或者您可以创建传统的AppKit应用程序并将SwiftUI视图插入其中。
CommandGroupPlacement
,因此我无法使用官方方式删除它。我可以通过 let fileMenu = items.first { $0.title == "File" }
获取文件菜单,并通过 fileMenu?.submenu?.items.first {$0.title == "Share"}
获取共享菜单命令。但是,我无法弄清楚如何使用 KVO 观察者来检测 SwiftUI 何时重新添加共享命令。 - Peter NowellNotificationCenter.default.publisher(for: NSMenu.didAddItemNotification, object: nil)
代替KVO,并且每次检查它是否是你想要删除的项目(例如“分享”)。然后在它是时将其删除。我发现在这一点上操纵菜单太麻烦了。 - waggles您可以通过AppDelegate文件删除命令菜单项:
override func buildMenu(with builder: UIMenuBuilder) {
super.buildMenu(with: builder)
builder.remove(menu: .services)
builder.remove(menu: .format)
builder.remove(menu: .toolbar)
}
这个苹果开发者论坛的帖子也许会有所帮助:https://developer.apple.com/forums/thread/649096
final class AppDelegate: NSObject, NSApplicationDelegate {
func applicationDidFinishLaunching(_ notification: Notification) {
let unwantedMenus = ["File", "Edit"]
let removeMenus = {
unwantedMenus.forEach {
guard let menu = NSApp.mainMenu?.item(withTitle: $0) else { return }
NSApp.mainMenu?.removeItem(menu)
}
}
NotificationCenter.default.addObserver(
forName: NSMenu.didAddItemNotification,
object: nil,
queue: .main
) { _ in
// Must refresh after every time SwiftUI re adds
removeMenus()
}
removeMenus()
}
CommandGroup(replacing: CommandGroupPlacement.appVisibility, addition: {})
applicationDidFinishLaunching
下面。注意:applicationWillUpdate
被频繁调用,永远不会停止。 - danneu