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

如何检测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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 09:15:12