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

如何使NSMenu中的SwiftUI视图可点击?Swift菜单栏应用开发

解决NSMenu中SwiftUI视图不可点击的问题

下面是针对你的问题的修复步骤和修改后的代码:

1. 修复SwiftUI视图的状态绑定

你的MainView中缺少Picker绑定所需的状态变量,这会导致Picker无法响应交互。添加@State属性并调整布局:

struct MainView: View {
    @State private var selectedHours = 0
    @State private var selectedMinutes = 0
    
    var body: some View {
        VStack {
            Picker("Hour", selection: $selectedHours) {
                ForEach(0...4, id: \.self) { hour in
                    Text("\(hour)")
                }
            }
            .pickerStyle(.menu)
            
            Picker("Min", selection: $selectedMinutes) {
                ForEach(0...60, id: \.self) { minute in
                    Text("\(minute)")
                }
            }
            .pickerStyle(.menu)
        }
        .padding()
    }
}

2. 修复NSMenu和NSHostingController的配置

原代码存在几个关键问题:未返回创建好的menu、未设置视图的自动调整掩码、未确保菜单项和视图处于启用状态。修改后的代码如下:

class ApplicationMenu: NSObject {
    let menu = NSMenu()
    
    func createMenu() -> NSMenu {
        let mainView = MainView()
        let topView = NSHostingController(rootView: mainView)
        
        // 设置自动调整掩码,确保视图能接收交互事件
        topView.view.autoresizingMask = [.width, .height]
        topView.view.frame = CGRect(x: 0, y: 0, width: 300, height: 200)
        topView.view.isEnabled = true
        
        let customMenuItem = NSMenuItem()
        customMenuItem.view = topView.view
        customMenuItem.isEnabled = true
        menu.addItem(customMenuItem)
        menu.addItem(NSMenuItem.separator())
        
        return menu // 必须返回创建好的菜单实例
    }
}

关键修复点说明

  • 状态绑定:Picker依赖@State或其他绑定类型来跟踪选择,没有状态变量的话视图会处于不可交互状态。
  • 自动调整掩码:设置autoresizingMask能确保SwiftUI视图在NSMenu中正确布局,同时保证事件能传递到视图内部。
  • 启用状态:显式设置isEnabled为true,避免系统默认将视图或菜单项标记为禁用。
  • 返回菜单实例:原代码漏掉了return menu,导致创建的菜单无法被正确使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 04:15:17