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

如何在iOS 18中用SwiftUI实现RealityView立体AR显示

双屏AR显示在RealityView中失效的问题解决

问题描述

此前在Storyboard+Swift+SceneKit环境下成功实现适配VR Box的双屏AR显示效果,但切换到RealityView后功能失效:仅左侧AR画面正常,右侧画面静止且尺寸偏小。目标是在iPhone上实现双屏AR显示立方体,打造AR/XR视图。

原实现代码:

import SwiftUI
import RealityKit

struct ContentView : View {
    var body: some View {
        HStack (spacing: 0){
            MainView()
            MainView()
        }
        .background(.black)
    }
}

struct MainView : View {
    @State var anchor = AnchorEntity()

    var body: some View {
        RealityView { content in
            let item = ModelEntity(mesh: .generateBox(size: 0.2), materials: [SimpleMaterial()])

            content.camera = .spatialTracking
            anchor.addChild(item)
            anchor.position = [0.0, 0.0, -1.0]
            anchor.orientation = .init(angle: .pi/4, axis:[0,1,1])

            // Add the horizontal plane anchor to the scene
            content.add(anchor)
        }
    }
}

问题根源

  • 重复空间追踪冲突:每个MainView都独立设置content.camera = .spatialTracking,但iOS仅支持一个活跃的空间追踪相机实例,第二个RealityView无法获取有效追踪数据,导致画面静止。
  • 布局未强制等分:两个RealityView默认尺寸计算未适配双屏场景,引发右侧画面尺寸偏小。
  • 锚点状态不共享:两个视图使用各自独立的AnchorEntity,无法保持双屏内容的同步性。

解决方案与修改代码

核心调整思路

  1. 父视图统一管理共享锚点和空间追踪上下文,确保双屏同步
  2. 为左右视图设置独立相机实体并添加双目偏移,模拟人眼间距
  3. 强制双屏等分布局,修正尺寸问题

修改后的完整代码:

import SwiftUI
import RealityKit

struct ContentView : View {
    // 共享锚点与空间追踪配置
    @State private var sharedAnchor = AnchorEntity()
    @State private var trackingMode = RealityView.Camera.TrackingMode.continuous
    
    var body: some View {
        HStack(spacing: 0) {
            ARSubView(sharedAnchor: sharedAnchor, trackingMode: trackingMode, eyeOffset: -0.03)
                .frame(maxWidth: .infinity, maxHeight: .infinity)
            
            ARSubView(sharedAnchor: sharedAnchor, trackingMode: trackingMode, eyeOffset: 0.03)
                .frame(maxWidth: .infinity, maxHeight: .infinity)
        }
        .background(.black)
        .onAppear {
            // 父视图中统一创建立方体并绑定到共享锚点
            let cube = ModelEntity(mesh: .generateBox(size: 0.2), materials: [SimpleMaterial()])
            cube.position = [0.0, 0.0, -1.0]
            cube.orientation = .init(angle: .pi/4, axis: [0,1,1])
            sharedAnchor.addChild(cube)
        }
    }
}

struct ARSubView: View {
    let sharedAnchor: AnchorEntity
    let trackingMode: RealityView.Camera.TrackingMode
    let eyeOffset: Float // 双目水平偏移量,模拟人眼间距
    
    var body: some View {
        RealityView { content in
            // 添加共享锚点到当前视图场景
            content.add(sharedAnchor)
            
            // 创建独立相机实体并设置偏移
            let cameraEntity = CameraEntity()
            cameraEntity.camera = .init(projection: .perspectiveFieldOfView(.degrees(60)))
            cameraEntity.position = [eyeOffset, 0, 0]
            content.add(cameraEntity)
            
            // 绑定空间追踪到当前相机实体
            content.camera = .entity(cameraEntity, trackingMode: trackingMode)
        }
    }
}

关键修改说明

  • 共享锚点:立方体与锚点在父视图中统一初始化,两个子视图复用同一锚点,保证双屏内容完全同步
  • 独立相机实体:左右视图各创建专属相机,通过eyeOffset设置水平偏移实现VR双目效果,同时绑定同一追踪模式,确保追踪数据同步
  • 强制等分布局:用frame(maxWidth: .infinity)让两个视图均分屏幕宽度,解决右侧画面尺寸偏小问题

内容的提问来源于stack exchange,提问作者Ostoura

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 11:26:05