如何指定visionOS应用启动时显示的WindowGroup?
在visionOS SwiftUI应用中指定重启后默认打开的WindowGroup
问题描述
我在开发visionOS SwiftUI应用时使用了多个WindowGroup,遇到了窗口恢复的问题:当关闭所有窗口后重启应用,系统会默认打开最后关闭的那个WindowGroup,但我希望每次重启都默认打开第一个(根)WindowGroup。
复现代码如下:
主App代码:
import SwiftUI @main struct demoApp: App { var body: some Scene { WindowGroup { FirstView() } WindowGroup(id: "second") { SecondView() } } }
FirstView:
import SwiftUI struct FirstView: View { @Environment(\.openWindow) var openWindow var body: some View { VStack { Text("First window group") Button("Open second window group") { openWindow(id: "second") } } } }
SecondView:
import SwiftUI struct SecondView: View { var body: some View { Text("Second window group") } }
操作步骤:
- 应用启动显示第一个
WindowGroup; - 点击按钮打开第二个
WindowGroup; - 关闭第一个窗口,再关闭第二个窗口;
- 重启应用,发现打开的是第二个
WindowGroup,不符合预期。
解决方案
要覆盖系统默认的窗口恢复行为,可通过以下两种方式实现:
方案一:使用onLaunch强制打开主窗口
visionOS支持onLaunch修饰符,可在应用启动时直接指定要打开的窗口,覆盖系统自动恢复逻辑。需给主WindowGroup设置明确ID,启动时调用openWindow打开它,同时关闭可能被恢复的其他窗口。
修改后的App代码:
import SwiftUI @main struct demoApp: App { @Environment(\.openWindow) private var openWindow @Environment(\.dismissWindow) private var dismissWindow var body: some Scene { // 给主WindowGroup设置唯一ID WindowGroup(id: "main") { FirstView() } WindowGroup(id: "second") { SecondView() } .onLaunch { // 关闭系统可能恢复的第二个窗口 dismissWindow(id: "second") // 强制打开主窗口 openWindow(id: "main") } } }
方案二:监听场景状态,确保主窗口存在
通过监听scenePhase,当应用进入活跃状态时,检查主窗口是否存在,若不存在则打开它。这种方式可处理应用从后台唤醒等场景,覆盖范围更广。
修改后的App代码:
import SwiftUI @main struct demoApp: App { @Environment(\.openWindow) private var openWindow @Environment(\.scenePhase) private var scenePhase var body: some Scene { WindowGroup(id: "main") { FirstView() } WindowGroup(id: "second") { SecondView() } .onChange(of: scenePhase) { newPhase in guard newPhase == .active else { return } // 检查当前是否存在主窗口 let hasMainWindow = UIApplication.shared.connectedScenes.contains { scene in guard let windowScene = scene as? UIWindowScene else { return false } return windowScene.session.configuration.sceneIdentifier == "main" } if !hasMainWindow { openWindow(id: "main") } } } }
说明:
- 两种方案都需要给主
WindowGroup设置明确ID,确保能精准控制目标窗口; - 方案一适合仅需在启动时强制打开主窗口的场景,方案二更灵活,可覆盖应用后台恢复等场景。
内容的提问来源于stack exchange,提问作者ihu
相关产品推荐
相关产品推荐

