You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mac Catalyst下NSStatusItem菜单显示正常但点击动作无响应

解决Mac Catalyst下NSStatusItem菜单项点击无响应的问题

问题原因分析

你的代码存在两个核心问题,导致菜单项点击动作无法触发:

  1. StatusBarItemControler未继承NSObject,而标注@objc的方法必须在NSObject子类中才能被Objective-C运行时识别(Mac Catalyst的AppKit组件依赖Objective-C消息机制)。
  2. 添加菜单项时未设置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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 18:50:25