ARKit 相机跟踪状态无法在 SwiftUI 上显示

问题描述 投票:0回答:1

我试图在设备屏幕顶部显示相机跟踪状态信息,但我的所有努力仍然出现错误。我对 ARView 如何与 SwiftUI 配合使用感到非常困惑,显示 AR 体验并在其上添加按钮图标很简单,但从会话中获取数据看起来需要做更多工作,有人可以帮助我吗?谢谢!

ViewModel 中的错误:“描述是仅获取属性”

内容视图

import SwiftUI
import ARKit
import RealityKit

struct ContentView: View {
    @StateObject var vm = ViewModel()
    
    var body: some View {
        ZStack{
            ARViewContainer()
                .edgesIgnoringSafeArea(.all)
                .environmentObject(vm)
            VStack{
                Text(vm.sessionInfoLabel)
                    .font(.title3)
                    .foregroundColor(.red)
                
                Spacer()
                HStack{
                    Button{
                        
                    } label: {
                        Image(systemName: "person.2")
                            .padding()
                            .font(.title)
                    }
                    Spacer()
                    Button{
                        
                    } label: {
                        Image(systemName: "target")
                            .padding()
                            .font(.title)
                    }
                }
                .padding()
                
            }
        }
    }
}

struct ARViewContainer: UIViewRepresentable {
    @EnvironmentObject var vm: ViewModel
    func makeUIView(context: Context) -> ARView {
        return vm.arView
    }
    
    func updateUIView(_ uiView: ARView, context: Context) {
    }
}

视图模型

import SwiftUI
import ARKit
import RealityKit

class ViewModel: ObservableObject {
    @Published var arView: ARView
    var sessionInfoLabel = ""
    init() {
        arView = ARView.init(frame: .zero)
        let config = ARWorldTrackingConfiguration()
        config.planeDetection = .horizontal
        arView.session.delegate = arView
        arView.session.run(config)
    }
}


extension ARView: ARSessionDelegate {
    public func session(_ session: ARSession, cameraDidChangeTrackingState camera: ARCamera) {
        camera.trackingState.description = ViewModel().sessionInfoLabel
    }
}

extension ARCamera.TrackingState: CustomStringConvertible {
    public var description: String {
        switch self {
        case .normal:
            return "Normal"
        case .notAvailable:
            return "Not Available"
        case .limited(.initializing):
            return "Initializing"
        case .limited(.excessiveMotion):
            return "Excessive Motion"
        case .limited(.insufficientFeatures):
            return "Insufficient Features"
        case .limited(.relocalizing):
            return "Relocalizing"
        case .limited:
            return "Unspecified Reason"
        }
    }
}
swift swiftui arkit realitykit
1个回答
0
投票

将此 SwiftUI 代码与协调器一起使用来表示 AR 相机的所有七种跟踪状态。

import SwiftUI
import ARKit
import RealityKit

struct ARContainer : UIViewRepresentable {
    @Binding var string: String
    var arView: ARView
    
    final class Coordinator : NSObject, ARSessionDelegate {
        var control: ARContainer

        init(_ control: ARContainer) {
            self.control = control
        }
        
        func session(_ session: ARSession,
                     cameraDidChangeTrackingState camera: ARCamera) {
            control.string = camera.trackingState.description
        }
    }
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }
    func makeUIView(context: Context) -> ARView {
        arView.session.delegate = context.coordinator
        arView.automaticallyConfigureSession = false
        
        let config = ARWorldTrackingConfiguration()
        config.planeDetection = .horizontal
        arView.session.run(config)
        return arView
    }
    func updateUIView(_ view: ARView, context: Context) { }
}

struct ContentView : View {
    @State var string = "Camera Trackimg State"
    let arView = ARView(frame: .zero)
    
    var body: some View {
        ZStack {
            ARContainer(string: $string, arView: arView)
                .ignoresSafeArea()
            
            Text(string)
                .font(.largeTitle)
                .foregroundStyle(.white)
        }
    }
}

extension ARCamera.TrackingState : CustomStringConvertible {
    public var description: String {
        switch self {
            case .normal:
                return "Normal"
            case .notAvailable:
                return "Not Available"
            case .limited(.initializing):
                return "Initializing"
            case .limited(.excessiveMotion):
                return "Excessive Motion"
            case .limited(.insufficientFeatures):
                return "Insufficient Features"
            case .limited(.relocalizing):
                return "Relocalizing"
            case .limited:
                return "Unspecified Reason"
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.