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

为何MenuBarExtra中的MenuPanel无法渲染List组件?

为什么MenuBarExtra的MenuPanel中List组件无法渲染?

我是Swift、SwiftUI和AppKit的新手,正在使用MenuBarExtra开发macOS菜单栏应用,请问为何MenuPanel中的List组件无法渲染?

代码示例

MacOSSoundUtilityApp.swift

import SwiftUI

@main
struct MacOSSoundUtilityApp: App {    
    var body: some Scene {
        MenuBarExtra("Utility App", systemImage: "hammer") {
            MenuPanel()
        }
        .menuBarExtraStyle(.menu)
    }
}

MenuPanel.swift

import Foundation
import SwiftUI

struct SomeApp: Identifiable {
    let name: String
    let id = UUID()
}

struct MenuPanel: View {
    var applications = [SomeApp(name: "app 1"), SomeApp(name: "app 2"), SomeApp(name: "app 3")]
    
    var body: some View {
        VStack {
            Text("Utility App")
                .font(.title)
            List {
                Text("option1")
                Text("option2")
                Text("option3")
            }
            List (applications) {
                Text($0.name)
            }
            Text("Hello")
        }
    }
}

问题原因

当你使用.menuBarExtraStyle(.menu)时,MenuBarExtra的内容是基于AppKit的NSMenu实现的。而SwiftUI的List是包含滚动逻辑的复杂视图组件,NSMenu仅支持原生菜单元素(如Button、MenuItem等),无法兼容这类非菜单原生的滚动容器,因此List无法被正确渲染。

解决方法

根据你的需求选择以下两种方案:

方案1:改用窗口样式的MenuBarExtra

将.menuBarExtraStyle(.menu)改为.menuBarExtraStyle(.window),此时MenuBarExtra会以独立窗口承载内容,支持所有SwiftUI视图组件,包括List:

@main
struct MacOSSoundUtilityApp: App {    
    var body: some Scene {
        MenuBarExtra("Utility App", systemImage: "hammer") {
            MenuPanel()
        }
        .menuBarExtraStyle(.window) // 修改为窗口样式
    }
}

方案2:用原生菜单组件替代List

如果必须保留.menu样式,需使用Menu或ForEach配合Button模拟菜单选项,这些是NSMenu支持的原生元素:

struct MenuPanel: View {
    var applications = [SomeApp(name: "app 1"), SomeApp(name: "app 2"), SomeApp(name: "app 3")]
    
    var body: some View {
        VStack {
            Text("Utility App")
                .font(.title)
            // 用Menu组件替代List
            Menu("Options") {
                Button("option1") {}
                Button("option2") {}
                Button("option3") {}
            }
            // 用ForEach+Button替代绑定数据源的List
            ForEach(applications) { app in
                Button(app.name) {}
            }
            Text("Hello")
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 12:37:47