RoomCaptureSession与SwiftUI集成报错:缺少frame参数求助
RoomPlan API结合SwiftUI的问题解决
核心问题分析
- 单例初始化错误:
CustomCaptureView继承自ARView,而ARView没有无参初始化器,必须通过init(frame:)创建实例,直接调用CustomCaptureView()会提示缺少frame参数。 - UIViewRepresentable返回类型不匹配:
RoomCaptureViewRep的makeUIView方法声明返回CustomCaptureView,但当前代码返回的是CustomCaptureView.shared.captureSession(类型为RoomCaptureSession),类型完全不兼容。
修改后的代码实现
1. 修复CustomCaptureView类
import Foundation import ARKit import RealityKit import RoomPlan class CustomCaptureView: ARView, RoomCaptureSessionDelegate { // 修复单例初始化,传入屏幕 bounds 作为 frame static var shared = CustomCaptureView(frame: UIScreen.main.bounds) let captureSession: RoomCaptureSession = RoomCaptureSession() let roomBuilder: RoomBuilder = RoomBuilder(options: [.beautifyObjects]) required init(frame: CGRect) { super.init(frame: frame) initSession() } @MainActor required dynamic init?(coder decoder: NSCoder) { super.init(coder: decoder) initSession() } func initSession() { self.cameraMode = .ar captureSession.delegate = self self.session = captureSession.arSession // 启动捕获会话,否则无法开始扫描 captureSession.startRunning() } func captureSession(_ session: RoomCaptureSession, didUpdate capturedRoom: CapturedRoom) { DispatchQueue.main.async { self.scene.anchors.removeAll() for wall in capturedRoom.walls { self.drawBox(scene: self.scene, dimensions: wall.dimensions, transform: wall.transform, confidence: wall.confidence) } for object in capturedRoom.objects { self.drawBox(scene: self.scene, dimensions: object.dimensions, transform: object.transform, confidence: object.confidence) } } } func drawBox(scene: Scene, dimensions: simd_float3, transform: float4x4, confidence: CapturedRoom.Confidence) { // 示例:生成半透明彩色盒子替代识别对象 let mesh = MeshResource.generateBox(size: dimensions) let color: UIColor = switch confidence { case .high: .systemBlue.withAlphaComponent(0.3) case .medium: .systemYellow.withAlphaComponent(0.3) case .low: .systemRed.withAlphaComponent(0.3) @unknown default: .systemGray.withAlphaComponent(0.3) } let material = SimpleMaterial(color: color, isMetallic: false) let entity = ModelEntity(mesh: mesh, materials: [material]) entity.transform = Transform(matrix: transform) scene.addAnchor(entity) } func captureSession(_ session: RoomCaptureSession, didEndWith data: CapturedRoomData, error: Error?) { // 处理会话结束逻辑 if let error = error { print("捕获会话出错:\(error.localizedDescription)") } else { print("捕获完成,可导出数据:\(data)") } } }
2. 修复RoomCaptureViewRep结构体
import SwiftUI import RoomPlan import ARKit import RealityKit struct RoomCaptureViewRep : UIViewRepresentable { func makeUIView(context: Context) -> CustomCaptureView { // 返回正确的CustomCaptureView实例 CustomCaptureView.shared } func updateUIView(_ uiView: CustomCaptureView, context: Context) {} } struct ActivityViewControllerRep: UIViewControllerRepresentable { var items: [Any] var activities: [UIActivity]? = nil func makeUIViewController(context: Context) -> UIActivityViewController { let controller = UIActivityViewController(activityItems: items, applicationActivities: activities) return controller } func updateUIViewController(_ uiViewController: UIActivityViewController, context: Context) {} } struct ContentView: View { var body: some View { RoomCaptureViewRep() .edgesIgnoringSafeArea(.all) // 让AR视图占满屏幕 } }
额外注意事项
- 必须在
Info.plist中添加权限声明:NSCameraUsageDescription(相机权限说明),如果需要空间定位还需添加NSLocationWhenInUseUsageDescription。 - 测试时需使用支持ARKit的真实iOS设备,模拟器无法运行AR相关功能。
内容的提问来源于stack exchange,提问作者Helge
相关产品推荐
相关产品推荐

