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

如何仅在特定macOS版本中通过SceneBuilder添加MenuBarExtra场景?

解决SwiftUI跨版本适配MenuBarExtra编译失败问题

问题原因

SwiftUI的SceneBuilder结果构建器(对应macOS 12的SwiftUI版本)不允许直接在body闭包内使用if #available这类控制流语句,因此直接写入条件分支会触发编译错误。

可行解决方案

方案一:封装条件场景为单独结构体

将仅在macOS 13+可用的MenuBarExtra场景封装成独立的Scene结构体,通过@available标记版本限制,再在主App的body中条件引入:

// 单独封装MenuBarExtra场景
@available(macOS 13.0, *)
struct AppMenuBarScene: Scene {
    @ObservedObject var viewModel: ViewModel
    
    var body: some Scene {
        MenuBarExtra() {
            MenuBarExtraContent(model: viewModel)
        } label: {
            MenuBarExtraLabel(model: viewModel)
        }
    }
}

@main
struct MyApp: App {
    @ObservedObject public var userSettings: UserSettings
    @ObservedObject public var viewModel: ViewModel
    /* 更多变量和初始化器声明 */

   var body: some Scene {
        WindowGroup("Pipelines") {
            PipelineListView(model: viewModel, settings: userSettings)
        }
        .commands {
            AppCommands()
        }
        Settings {
            SettingsView(settings: userSettings)
        }
        // 条件引入封装好的场景
        if #available(macOS 13.0, *) {
            AppMenuBarScene(viewModel: viewModel)
        }
    }
}

方案二:使用可选场景属性

把版本判断逻辑移到返回可选Scene的计算属性中,SceneBuilder会自动忽略nil值,无需在body内写控制流:

@main
struct MyApp: App {
    @ObservedObject public var userSettings: UserSettings
    @ObservedObject public var viewModel: ViewModel
    /* 更多变量和初始化器声明 */
    
    // 计算属性返回可选的MenuBarExtra场景
    private var menuBarScene: some Scene? {
        guard #available(macOS 13.0, *) else {
            return nil
        }
        return MenuBarExtra() {
            MenuBarExtraContent(model: viewModel)
        } label: {
            MenuBarExtraLabel(model: viewModel)
        }
    }

   var body: some Scene {
        WindowGroup("Pipelines") {
            PipelineListView(model: viewModel, settings: userSettings)
        }
        .commands {
            AppCommands()
        }
        Settings {
            SettingsView(settings: userSettings)
        }
        // 直接引用可选属性,旧系统下自动忽略
        menuBarScene
    }
}

方案特点

  • 方案一更适合复杂场景,代码结构清晰,便于后续维护扩展;
  • 方案二更简洁,适合简单的条件场景实现。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 17:55:59