如何检测Immersive Space被外部操作关闭并执行对应代码?
检测Immersive Space被外部操作关闭并实现场景重置
要实现这个需求,你可以借助SwiftUI提供的Immersive Space生命周期回调和场景状态监听来完成,具体实现方案如下:
1. 精准监听Immersive Space关闭事件
使用onImmersiveSpaceChange回调可以直接捕获Immersive Space的状态变化,包括被外部操作(比如头戴设备顶部按钮、其他应用弹窗)触发的关闭:
struct ImmersiveView: View { @Environment(\.dismissImmersiveSpace) private var dismissImmersiveSpace var body: some View { ImmersiveSpace(id: "MainImmersive") { // 你的沉浸式场景内容 } .onImmersiveSpaceChange { state in if state == .closed { // 检测到关闭事件,执行场景重置 resetScene() } } } private func resetScene() { // 写入场景重置逻辑: // 例如重置游戏状态、释放3D资源、停止音频播放等 // gameSession.reset() // assetCache.unloadAllAssets() } }
2. 结合ScenePhase处理后台切换场景
当响应其他应用弹窗时,Immersive Space会先进入后台状态,你可以通过@Environment(\.scenePhase)监听这个变化,提前做临时状态保存或轻量清理:
struct ImmersiveView: View { @Environment(\.scenePhase) private var scenePhase var body: some View { ImmersiveSpace(id: "MainImmersive") { // 场景内容 } .onChange(of: scenePhase) { _, newPhase in if newPhase == .background { // 场景进入后台,保存临时数据避免丢失 saveTemporaryState() } } .onImmersiveSpaceChange { state in if state == .closed { resetScene() } } } private func saveTemporaryState() { // 保存当前场景临时状态 } }
3. 实现用户重新启动功能
在主界面中维护一个状态变量标记Immersive Space的活跃状态,根据状态显示启动按钮:
// App结构体中管理全局状态 @main struct MyImmersiveApp: App { @State private var isImmersiveActive = false var body: some Scene { WindowGroup { ContentView(isImmersiveActive: $isImmersiveActive) } ImmersiveSpace(id: "MainImmersive") { ImmersiveView() } .onChange(of: $0) { state in isImmersiveActive = state == .open if state == .closed { resetGlobalSceneState() } } } private func resetGlobalSceneState() { // 全局场景重置操作 } } // 主界面ContentView struct ContentView: View { @Environment(\.openImmersiveSpace) private var openImmersiveSpace @Binding var isImmersiveActive: Bool var body: some View { VStack(spacing: 20) { if !isImmersiveActive { Button("启动沉浸式场景") { Task { let result = await openImmersiveSpace(id: "MainImmersive") isImmersiveActive = result == .opened } } .buttonStyle(.borderedProminent) } } .padding() } }
关键提示
onImmersiveSpaceChange是最精准的监听方式,能直接识别.closed状态,不受关闭触发源(内部/外部)影响。- 重置场景时务必释放所有占用的资源,比如卸载3D模型、停止动画和音频,避免内存泄漏。
- 如果需要区分“主动关闭”和“外部强制关闭”,可以在内部关闭方法中设置标记,在
onImmersiveSpaceChange中判断标记执行不同逻辑。
内容的提问来源于stack exchange,提问作者Anthony Harvey
相关产品推荐
相关产品推荐

