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

MacOS应用如何自定义App菜单中「设置...」(Cmd+,)的触发动作?

定位并修改MacOS应用的「设置」菜单项

方法1:通过Action和快捷键定位(最可靠)

系统默认的「设置」菜单项Action固定为showPreferences:,快捷键是Cmd+,——不管菜单标题因本地化如何变化,这两个标识始终稳定。可以通过递归遍历菜单栏,匹配属性来定位目标菜单项:

import AppKit

func findPreferencesMenuItem() -> NSMenuItem? {
    guard let mainMenu = NSApp.mainMenu else { return nil }
    
    // 递归遍历所有菜单项
    func searchMenuItems(in menu: NSMenu) -> NSMenuItem? {
        for item in menu.items {
            if item.action == Selector(("showPreferences:")) 
                && item.keyEquivalent == "," 
                && item.keyEquivalentModifierMask == .command {
                return item
            }
            if let submenu = item.submenu {
                if let foundItem = searchMenuItems(in: submenu) {
                    return foundItem
                }
            }
        }
        return nil
    }
    
    return searchMenuItems(in: mainMenu)
}

// 使用示例
if let preferencesItem = findPreferencesMenuItem() {
    // 修改菜单项的Action为自定义方法
    preferencesItem.action = #selector(YourViewController.customPreferencesAction(_:))
    // 也可以直接替换整个菜单项
    let newItem = NSMenuItem(title: "自定义设置...", action: #selector(YourViewController.customPreferencesAction(_:)), keyEquivalent: ",")
    newItem.keyEquivalentModifierMask = .command
    if let parentMenu = preferencesItem.parent {
        let index = parentMenu.items.firstIndex(of: preferencesItem)!
        parentMenu.replaceItem(at: index, with: newItem)
    }
}

// 自定义Action示例
@objc func customPreferencesAction(_ sender: Any?) {
    // 执行你的自定义设置逻辑
}

方法2:通过菜单标题定位(适合固定本地化场景)

如果你的应用只针对特定语言环境发布,可以直接匹配菜单标题(比如中文的「设置...」,英文的「Preferences...」):

func findPreferencesMenuItemByTitle() -> NSMenuItem? {
    guard let mainMenu = NSApp.mainMenu else { return nil }
    
    func searchMenuItems(in menu: NSMenu) -> NSMenuItem? {
        for item in menu.items {
            if item.title == "设置..." { // 中文环境,英文替换为"Preferences..."
                return item
            }
            if let submenu = item.submenu {
                if let foundItem = searchMenuItems(in: submenu) {
                    return foundItem
                }
            }
        }
        return nil
    }
    
    return searchMenuItems(in: mainMenu)
}

方法3:直接重新构建应用菜单(完全自定义)

如果需要彻底替换默认菜单结构,可以直接创建新的NSMenu并赋值给NSApp.mainMenu,其中包含自定义的设置菜单项:

func setupCustomMainMenu() {
    let mainMenu = NSMenu()
    
    // 应用菜单(比如「你的应用名」菜单)
    let appMenu = NSMenu(title: "")
    let preferencesItem = NSMenuItem(title: "设置...", action: #selector(YourViewController.customPreferencesAction(_:)), keyEquivalent: ",")
    preferencesItem.keyEquivalentModifierMask = .command
    appMenu.addItem(preferencesItem)
    // 添加其他默认菜单项(比如关于、退出等)
    appMenu.addItem(NSMenuItem.separator())
    appMenu.addItem(NSMenuItem(title: "退出 \(Bundle.main.displayName!)", action: #selector(NSApp.terminate(_:)), keyEquivalent: "q"))
    
    mainMenu.addItem(NSMenuItem(title: Bundle.main.displayName!, submenu: appMenu))
    // 添加其他菜单(比如文件、编辑等)
    
    NSApp.mainMenu = mainMenu
}

注意:如果用SwiftUI开发,可以在App结构体中通过NSApplicationDelegateAdaptor实现上述逻辑,或者在@main类中重写applicationDidFinishLaunching方法执行定位修改操作。

内容的提问来源于stack exchange,提问作者Kaven

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 23:16:03