我正在为 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 演讲中找不到对此的明确描述。任何帮助将不胜感激!
亲切的问候, 蒂森
对于遇到同样问题的人,我还向 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 { ... }
初始化程序来说是不正确的。