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

SwiftUI macOS菜单:如何实现带复选标记与快捷键的可选菜单项?

问题解答

这是SwiftUI在macOS上的已知限制,当使用.inline样式的Picker包裹带keyboardShortcut的Button时,Picker会拦截按钮的快捷键绑定,导致快捷键失效。并非你的操作有误。

替代方案1:用Menu + Toggle实现(推荐)

放弃Picker,直接用Menu结合Toggle组件,既能实现复选标记,又能正常绑定快捷键:

@State private var selection = 1

Menu("自定义菜单") {
    Toggle("Test 1", isOn: Binding(
        get: { selection == 1 },
        set: { _ in selection = 1 }
    ))
    .keyboardShortcut("1")
    
    Toggle("Test 2", isOn: Binding(
        get: { selection == 2 },
        set: { _ in selection = 2 }
    ))
    .keyboardShortcut("2")
}

这种方式利用Toggle的选中状态模拟单选/多选效果,同时快捷键可以正常触发。如果是单选场景,通过绑定的get/set逻辑确保同一时间只有一个选项被选中。

替代方案2:结合AppKit手动添加快捷键(适合坚持用Picker的场景)

如果必须使用Picker,可以通过AppKit的NSMenuItem手动为对应的动作添加全局快捷键,绕开SwiftUI的限制:

@State private var selection = 1
@NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate

class AppDelegate: NSObject, NSApplicationDelegate {
    func applicationDidFinishLaunching(_ notification: Notification) {
        // 为Test 1添加快捷键
        let test1MenuItem = NSMenuItem(title: "Test 1", action: #selector(test1Action), keyEquivalent: "1")
        test1MenuItem.keyEquivalentModifierMask = [] // 可根据需求添加Command/Shift等修饰符
        NSApp.mainMenu?.item(withTitle: "你的菜单栏名称")?.submenu?.addItem(test1MenuItem)
    }
    
    @objc func test1Action() {
        // 更新SwiftUI的selection状态
        let contentView = NSApp.windows.first?.contentViewController as? NSHostingController<ContentView>
        contentView?.rootView.selection = 1
    }
}

// ContentView中的Picker部分
Picker(selection: $selection) {
    Button("Test 1") {}
        .tag(1)
}.pickerStyle(.inline)

这种方式需要手动管理AppKit的菜单层级,适合对原有Picker结构依赖较强的场景,但代码复杂度更高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 05:39:57