MapKit中用户位置蓝点显示及基于用户位置绘制导航折线问题
解决MapKit导航起点设为用户当前位置及显示用户蓝色标记的问题
一、显示用户位置的蓝色标记
SwiftUI的Map组件默认不会显示用户位置的蓝色标记,需要通过userTrackingMode开启位置跟踪:
- 在
ContentView中添加状态变量控制跟踪模式:@State private var userTrackingMode: MapUserTrackingMode = .follow - 给
Map添加修饰符启用位置跟踪:.userTrackingMode($userTrackingMode)
二、将导航起点设置为用户当前位置
关键修改步骤:
- 移除固定起点常量:删除原代码中
private let startingPoint的定义,改用newlocationManager中的实时位置作为起点。 - 监听位置更新:添加
onChange监听newlocationManager.location的变化,当位置更新且已设置目的地时,重新计算路线。 - 更新路线请求:修改
getDirections方法,将请求的source替换为用户当前位置对应的MKMapItem。
完整修改后的代码
import SwiftUI import MapKit import CoreLocation @Observable class NewLocationManager { var location: CLLocation? = nil private let locationManager = CLLocationManager() func requestUserAuthorization() async throws { locationManager.requestWhenInUseAuthorization() } func startCurrentLocationUpdates() async throws { for try await locationUpdate in CLLocationUpdate.liveUpdates() { guard let location = locationUpdate.location else { return } self.location = location print("当前位置: \(location.coordinate.latitude), \(location.coordinate.longitude)") } } } struct ContentView: View { @State var newlocationManager = NewLocationManager() @State private var selectedResult: MKMapItem? @State private var route: MKRoute? // 添加用户位置跟踪模式 @State private var userTrackingMode: MapUserTrackingMode = .follow private let destinationCoordinates = CLLocationCoordinate2D( latitude: 37.94479, longitude: -122.50959 ) var body: some View { VStack { Text("当前位置: \(newlocationManager.location?.coordinate.description ?? "未获取到位置")") .padding() Map(selection: $selectedResult) { // 仅当获取到用户位置时显示起点标记 if let userCoordinate = newlocationManager.location?.coordinate { Marker("我的位置", coordinate: userCoordinate) } // 显示导航路线 if let route { MapPolyline(route) .stroke(.blue, lineWidth: 5) } } .userTrackingMode($userTrackingMode) // 启用用户位置跟踪 .onChange(of: selectedResult) { getDirections() } // 监听用户位置变化,更新路线 .onChange(of: newlocationManager.location) { if selectedResult != nil { getDirections() } } .task { try? await newlocationManager.requestUserAuthorization() try? await newlocationManager.startCurrentLocationUpdates() } .onAppear { self.selectedResult = MKMapItem(placemark: MKPlacemark(coordinate: destinationCoordinates)) } } } func getDirections() { route = nil guard let selectedResult, let userCoordinate = newlocationManager.location?.coordinate else { return } let request = MKDirections.Request() // 使用用户当前位置作为起点 request.source = MKMapItem(placemark: MKPlacemark(coordinate: userCoordinate)) request.destination = selectedResult Task { let directions = MKDirections(request: request) do { let response = try await directions.calculate() route = response.routes.first } catch { print("路线计算失败: \(error.localizedDescription)") } } } } #Preview { ContentView() }
额外说明
- 确保在
Info.plist中添加NSLocationWhenInUseUsageDescription权限描述,否则无法获取用户位置。 - 位置更新是实时的,当用户移动时,路线会自动重新计算(如果目的地已设置)。
内容的提问来源于stack exchange,提问作者matarali
相关产品推荐
相关产品推荐

