SwiftUI异步加载Reality Composer场景并绑定ARViewContainer后如何触发通知?
问题:异步加载Reality Composer场景后无法触发通知
我希望在Reality Composer场景中使用Scene1.notifications.replay.post()这类通知功能,于是在SwiftUI的ContentView中异步加载场景并绑定到ARViewContainer添加场景,但操作无效,原代码如下:
struct ContentView: View { @State private var arView = ARView(frame: .zero) @State private var Scene1 = Experience.loadSceneAsync(completion: { result in do { let Scene = try result.get() } catch { print("Error") } }) var body: some View { ZStack { ARViewContainer(arView: $arView, Scene1: $Scene1) .ignoresSafeArea() Button("play") { Scene1.notifications.replay.post() } } } } struct ARViewContainer: UIViewRepresentable { @Binding var arView: ARView @Binding var Scene1: Experience1.Scene1 func makeUIView(context: Context) -> ARView { arView.scene.anchors.append(Scene1) return ARView } }
问题分析
loadSceneAsync是异步方法,返回值为Void,不能直接赋值给@State变量Scene1,原代码的异步回调未将加载后的场景实例保存到Scene1,导致后续调用通知时Scene1并非有效场景实例。ARViewContainer的makeUIView错误返回了ARView类型而非实例arView,且异步加载可能未完成时Scene1为空,直接添加锚点会失败。Scene1应定义为可选类型,适配异步加载未完成时的空状态。
修正后的代码
ContentView部分
struct ContentView: View { @State private var arView = ARView(frame: .zero) @State private var scene1: Experience1.Scene1? // 改为可选类型存储加载后的场景 var body: some View { ZStack { ARViewContainer(arView: $arView, scene1: $scene1) .ignoresSafeArea() Button("play") { scene1?.notifications.replay.post() // 用可选链避免空值崩溃 } } .onAppear { // 视图出现时启动异步加载 Experience.loadScene1Async { result in do { self.scene1 = try result.get() } catch { print("加载场景失败:\(error.localizedDescription)") } } } } }
ARViewContainer部分
struct ARViewContainer: UIViewRepresentable { @Binding var arView: ARView @Binding var scene1: Experience1.Scene1? func makeUIView(context: Context) -> ARView { return arView } func updateUIView(_ uiView: ARView, context: Context) { // 当scene1有值且未添加到锚点时,添加到ARView guard let scene = scene1, !uiView.scene.anchors.contains(scene) else { return } uiView.scene.anchors.append(scene) } }
关键修改说明
- 将
Scene1改为可选类型Experience1.Scene1?,适配异步加载未完成时的空状态。 - 在
onAppear中触发异步加载,将结果赋值给scene1,确保视图出现后才开始加载场景。 - 把场景添加逻辑移到
updateUIView方法中,该方法会在绑定的scene1变化时触发,保证场景加载完成后才添加到ARView锚点。 - 按钮触发通知时使用可选链
scene1?.notifications.replay.post(),避免场景未加载完成导致的崩溃。
内容的提问来源于stack exchange,提问作者kkk
相关产品推荐
相关产品推荐

