Mac Catalyst下NSStatusItem菜单显示正常但点击动作无响应
解决Mac Catalyst下NSStatusItem菜单项点击无响应的问题
问题原因分析
你的代码存在两个核心问题,导致菜单项点击动作无法触发:
StatusBarItemControler未继承NSObject,而标注@objc的方法必须在NSObject子类中才能被Objective-C运行时识别(Mac Catalyst的AppKit组件依赖Objective-C消息机制)。- 添加菜单项时未设置
target,默认target为nil,系统找不到执行动作方法的对象。
修改后的代码
@objc class AppKitController: NSObject { var statusBarItem: StatusBarItemControler! override init() { super.init() print("[AppKitController] Loaded successfully") self.statusBarItem = StatusBarItemControler() self.statusBarItem.updateTitle() self.statusBarItem.updateMenu() } } // 让类继承NSObject,确保@objc方法能被Objective-C运行时识别 @objc class StatusBarItemControler: NSObject { let item: NSStatusItem override init() { self.item = NSStatusBar.system.statusItem( withLength: NSStatusItem.variableLength ) let statusBarMenu = NSMenu(title: "APPMenu") self.item.menu = statusBarMenu super.init() // NSObject子类必须调用父类初始化方法 } func updateTitle() { let title = "AppMenu" print("Update title") DispatchQueue.main.async { if let button = self.item.button { button.title = "\(title)" // 按钮target与菜单动作无关,可按需保留或移除 button.target = self } } } func updateMenu() { if let statusBarMenu = self.item.menu { statusBarMenu.autoenablesItems = false statusBarMenu.removeAllItems() statusBarMenu.addItem(NSMenuItem.separator()) statusBarMenu.addItem(NSMenuItem.separator()) self.createPreferencesSection() } } func createPreferencesSection() { // 创建菜单项时显式设置target为当前实例 let openItem = NSMenuItem( withTitle: "Open", action: #selector(openPrefecencesWindow(_:)), keyEquivalent: "," ) openItem.target = self self.item.menu!.addItem(openItem) let quitItem = NSMenuItem( withTitle: "Quit", action: #selector(quit(_:)), keyEquivalent: "q" ) quitItem.target = self self.item.menu!.addItem(quitItem) } @objc func openPrefecencesWindow(_ sender: NSMenuItem?) { print("Open preferences window") } @objc func quit(_ sender: NSMenuItem?) { print("Quit app") NSApplication.shared.terminate(self) } }
关键修改说明
- 让
StatusBarItemControler继承NSObject并调用super.init(),确保@objc方法能被系统识别。 - 给每个菜单项设置
target = self,明确指定动作方法的执行对象。 - 调整动作方法的参数类型为
NSMenuItem?(菜单项的动作发送者本身是菜单项,更符合实际场景)。
内容的提问来源于stack exchange,提问作者Steven
相关产品推荐
相关产品推荐

