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

MapKit中用户位置蓝点显示及基于用户位置绘制导航折线问题

解决MapKit导航起点设为用户当前位置及显示用户蓝色标记的问题

一、显示用户位置的蓝色标记

SwiftUI的Map组件默认不会显示用户位置的蓝色标记,需要通过userTrackingMode开启位置跟踪:

  • 在ContentView中添加状态变量控制跟踪模式:
    @State private var userTrackingMode: MapUserTrackingMode = .follow
    
  • 给Map添加修饰符启用位置跟踪:
    .userTrackingMode($userTrackingMode)
    

二、将导航起点设置为用户当前位置

关键修改步骤:

  1. 移除固定起点常量:删除原代码中private let startingPoint的定义,改用newlocationManager中的实时位置作为起点。
  2. 监听位置更新:添加onChange监听newlocationManager.location的变化,当位置更新且已设置目的地时,重新计算路线。
  3. 更新路线请求:修改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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 19:47:32