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

如何在SwiftUI的macOS多窗口(WindowGroup)中避免状态共享

SwiftUI多窗口场景:区分全局共享状态与窗口本地状态

我正在开发适配iOS/iPadOS/macOS的跨平台应用,需要在macOS上支持多窗口功能。通过WindowGroup已经实现了原生多窗口,也能通过状态栏打开新窗口,但目前无法正确区分全局共享状态和窗口本地状态。

我的需求是:打开新窗口时,Api对象在所有窗口间共享,NavManager对象则为每个窗口维护独立的状态。

以下是简化的应用入口代码:

import SwiftUI

@Observable class NavManager {
    enum NavItem {
        case a
        case b
    }
    
    var currentNav: NavItem = .a
}

@Observable class Api {
    var someProperty: String = "Hello World"
}


struct NavigationView: View {
    @State private var navManager: NavManager = NavManager()
    
    var body: some View {
        switch navManager.currentNav {
        case .a:
            Text("Navigated to a")
        case .b:
            Text("Navigated to b")
        }
        Button {
            if navManager.currentNav == .a {
                navManager.currentNav = .b
            } else {
                navManager.currentNav = .a
            }
        } label: {
            Text("Toggle navigation")
        }
        Text("Some subview hierarchy that needs navManager")
            .environment(navManager)
    }
}

@main
struct MPFApp: App {
    
    @State private var api: Api = Api()
    
    var body: some Scene {
        WindowGroup {
            NavigationView()
                .environment(api)
        }
    }
}

但当前代码存在问题:navManager的状态在多窗口间是共享的,切换一个窗口的导航状态时,其他窗口的导航状态会同步变化,不符合每个窗口独立维护导航状态的预期。我在Apple官网及WWDC演讲中未找到明确的说明。


更新:问题已解决

该功能现已正常工作,核心注意点是:不要在App视图中初始化NavManager,必须在NavigationView内部用@State初始化。

原理说明:WindowGroup每次创建新窗口时,会重新实例化其内部的整个视图层级。将NavManager的@State声明放在NavigationView内部,每个新窗口都会生成一个独立的NavManager实例,从而实现窗口本地状态的隔离;而Api在App层级用@State声明,会被所有窗口共享,保证全局状态的一致性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 18:15:02