我使用ARKit-CoreLocation库在AR
World中,在iOS 14
中呈现POI
。但问题是,我 * 不能 * 使用ARCL
的SceneLocationView
,因为它是SCNView
。所以当我将它作为子视图添加时,它覆盖了我的ARView
内容,并创建了一个新的ARSession
,将我的ARView
留在后台。
编码:
extension RealityKitViewController {
typealias Context = UIViewControllerRepresentableContext<RealityKitViewControllerRepresentable>
}
class RealityKitViewController: UIViewController {
let sceneLocationView = SceneLocationView()
let arView = ARView(frame: .zero)
let context : Context
let pins: [Pin]
var currentLocation : CLLocation? {
return sceneLocationView.sceneLocationManager.currentLocation
}
init (_ context : Context, pins: [Pin]) {
self.context = context
self.pins = pins
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func makeArView()
{
// Start AR session
let session = arView.session
let config = ARWorldTrackingConfiguration()
config.planeDetection = [.horizontal, .vertical]
session.run(config)
// Add coaching overlay
let coachingOverlay = ARCoachingOverlayView()
coachingOverlay.session = session
coachingOverlay.goal = .horizontalPlane
coachingOverlay.delegate = context.coordinator
arView.addSubview(coachingOverlay)
arView.debugOptions = [.showFeaturePoints, .showAnchorOrigins, .showAnchorGeometry]
// Handle ARSession events via delegate
context.coordinator.view = arView
session.delegate = context.coordinator
}
override func viewDidLoad() {
super.viewDidLoad()
// probably problem here
sceneLocationView.frame = view.bounds
arView.frame = sceneLocationView.bounds
sceneLocationView.addSubview(arView)
view.addSubview(sceneLocationView)
addPins()
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
sceneLocationView.frame = view.bounds
}
override func viewWillAppear(_ animated: Bool) {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
super.viewWillAppear(animated)
self.sceneLocationView.run()
}
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
sceneLocationView.pause()
}
func addPins() {
guard let currentLocation = currentLocation, currentLocation.horizontalAccuracy < 16 else {
return DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { [weak self] in
self?.addPins()
}
}
self.pins.forEach { pin in
guard pin.isLocation else { return }
guard let location = pin.location else { return assertionFailure() }
guard let image = UIImage(named: pin.image) else { return assertionFailure() }
let node = LocationAnnotationNode(location : location, image: image)
node.scaleRelativeToDistance = true
sceneLocationView.addLocationNodeWithConfirmedLocation(locationNode: node)
}
}
}
// if you want to test it, you can try to place these pins to a location where you can easily get coordinates from Google Earth.
struct RealityKitViewControllerRepresentable : UIViewControllerRepresentable {
let pins = [Pin(image: "test", location: CLLocation(coordinate: CLLocationCoordinate2D(latitude: 0.03275742958, longitude: 0.32827424), altitude: 772.1489524841309), isLocation: true)]
@Binding var arActivate : Bool
func makeUIViewController(context: Context) -> RealityKitViewController {
let viewController = RealityKitViewController(context, pins: pins)
return viewController
}
func updateUIViewController(_ uiViewController: RealityKitViewController, context: Context) {
}
func makeCoordinator() -> Coordinator {
Coordinator()
}
}
class Coordinator: NSObject, ARSessionDelegate {
weak var view: ARView?
}
1条答案
按热度按时间kx1ctssn1#
我解决了这个问题:没有解决办法。
使用
SCNView
作为一个子视图是一个非常可怕的想法,但我发现的每个答案都说“不”,似乎这个特性将一直悬而未决,直到Apple
发布一个集成或其他东西。