如何避免使用 SwiftUI 在 WindowGroup / 多屏 macOS 上共享状态?

问题描述 投票:0回答:1

我正在为 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 中维护的状态仍然在两个窗口之间共享,这意味着一个窗口中的导航将自动在另一个窗口中导航。

我在苹果网站或他们的 WWDC 演讲中找不到对此的明确描述。任何帮助将不胜感激!

亲切的问候, 蒂森

swift macos swiftui state
1个回答
0
投票

对于遇到同样问题的人,我还向 Apple 提交了错误报告。

同时,我能够使用非默认初始化程序解决该问题:

@main
struct UnboundApp: App {
    var body: some Scene {
        // Just a dummy type to force root-view instantiation:
        WindowGroup(for: UUID.self) { _ in
            Test()
    }
}
struct Test: View {
    init() {
        Logger().debug("Test init")
    }
    
    var body: some View {
        Text("Test")
    }
}

通过这种方式,我看到每个新窗口都打印了“Test init”,这对于默认的

WindowGroup { ... }
初始化程序来说是不正确的。

© www.soinside.com 2019 - 2024. All rights reserved.