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

SwiftUI中基于RealityKit与ARKit实现北向箭头及航向信息显示求助

在SwiftUI+ARKit中实现指向北方的航向箭头

核心实现思路

要实现始终指向正北的箭头,需要结合CoreLocation获取设备真北航向和SwiftUI叠加UI元素到AR视图两个核心步骤:

  1. 用CLLocationManager获取设备相对于真北的航向角度
  2. 在AR相机视图上层叠加箭头视图,根据实时航向旋转箭头,保持指向正北

完整代码实现

import SwiftUI
import ARKit
import CoreLocation

// 管理航向数据的Observable对象
class HeadingManager: NSObject, ObservableObject, CLLocationManagerDelegate {
    let locationManager = CLLocationManager()
    @Published var trueHeading: Double = 0.0
    
    override init() {
        super.init()
        locationManager.delegate = self
        // 请求位置权限(获取航向需要位置权限)
        locationManager.requestWhenInUseAuthorization()
        // 开始更新航向
        locationManager.startUpdatingHeading()
    }
    
    func locationManager(_ manager: CLLocationManager, didUpdateHeading newHeading: CLHeading) {
        // 仅当航向数据有效时更新
        if newHeading.headingAccuracy > 0 {
            trueHeading = newHeading.trueHeading
        }
    }
}

// SwiftUI包装ARView
struct ARViewContainer: UIViewRepresentable {
    func makeUIView(context: Context) -> ARView {
        let arView = ARView(frame: .zero)
        // 配置AR会话(基础AR相机模式)
        let configuration = ARWorldTrackingConfiguration()
        arView.session.run(configuration)
        return arView
    }
    
    func updateUIView(_ uiView: ARView, context: Context) {}
}

// 主视图
struct ARCompassView: View {
    @StateObject private var headingManager = HeadingManager()
    
    var body: some View {
        ZStack(alignment: .bottom) {
            // AR相机视图
            ARViewContainer()
            
            // 指向正北的箭头
            Image(systemName: "arrow.up")
                .font(.system(size: 40, weight: .bold))
                .foregroundColor(.white)
                .padding()
                .background(Color.black.opacity(0.7))
                .cornerRadius(10)
                .padding(.bottom, 30)
                // 根据真北航向旋转箭头:设备航向是相对于正北的顺时针角度,所以反转角度让箭头指向正北
                .rotationEffect(.degrees(-headingManager.trueHeading))
        }
        .onAppear {
            // 确保设备支持航向更新
            guard CLLocationManager.headingAvailable() else {
                print("设备不支持航向检测")
                return
            }
        }
    }
}

// 预览
struct ARCompassView_Previews: PreviewProvider {
    static var previews: some View {
        ARCompassView()
    }
}

关键细节说明

  • 权限配置:需要在Info.plist中添加以下权限描述,否则无法获取航向:
    <key>NSLocationWhenInUseUsageDescription</key>
    <string>需要获取设备航向以显示正北箭头</string>
    <key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
    <string>需要获取设备航向以显示正北箭头</string>
    
  • 真北 vs 磁北:代码中用的trueHeading是基于GPS的真北航向,如果你需要磁北,可以改用newHeading.magneticHeading
  • 箭头旋转逻辑:设备的trueHeading表示设备当前朝向与正北的顺时针夹角,所以给箭头设置-trueHeading的旋转角度,就能让箭头始终指向正北
  • 设备兼容性:部分旧设备可能不支持航向检测,代码中加入了headingAvailable()的判断,避免崩溃

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 23:01:07