如何在Cocoa macOS的AppDelegate中创建生效的主菜单及菜单项?
问题根源
脱离Storyboard启动的macOS应用,NSApp.mainMenu初始值为nil,你代码里的if let appMainMenu = NSApp.mainMenu分支不会执行,导致菜单构建逻辑完全未运行,这就是菜单不显示且无报错的原因。
修复代码
直接创建全新的主菜单实例并赋值给应用的mainMenu属性,替换原customMainMenu函数:
func customMainMenu() { // 初始化主菜单容器 let mainMenu = NSMenu() // 获取应用名称作为顶级菜单标题(遵循macOS规范) let appTitle = Bundle.main.infoDictionary?["CFBundleName"] as? String ?? "MyApp" let appTopMenuItem = NSMenuItem(title: appTitle, action: nil, keyEquivalent: "") // 创建应用菜单的子菜单 let appSubMenu = NSMenu(title: appTitle) // 添加Close选项 let closeMenuItem = NSMenuItem( title: "Close", action: #selector(NSWindow.performClose(_:)), keyEquivalent: "w" ) closeMenuItem.keyEquivalentModifierMask = .command // 添加Quit选项 let quitMenuItem = NSMenuItem( title: "Quit", action: #selector(NSApplication.shared.terminate(_:)), keyEquivalent: "q" ) quitMenuItem.keyEquivalentModifierMask = .command // 组装子菜单(可选添加分隔线) appSubMenu.addItem(closeMenuItem) appSubMenu.addItem(NSMenuItem.separator()) appSubMenu.addItem(quitMenuItem) // 关联子菜单到顶级菜单项 appTopMenuItem.submenu = appSubMenu // 将顶级菜单项加入主菜单 mainMenu.addItem(appTopMenuItem) // 给应用设置主菜单 NSApp.mainMenu = mainMenu }
补充说明
- 顶级菜单使用应用Bundle名称是macOS的标准UI设计,提升用户体验
- 分隔线可以让菜单选项分组更清晰,可根据需求移除
- 该函数在
applicationDidFinishLaunching中的调用位置不影响功能
内容的提问来源于stack exchange,提问作者swiftPunk
相关产品推荐
相关产品推荐

