如何在SwiftUI Map组件中实现两点之间的路线展示功能?
两点路线展示实现示例
你可以在现有代码基础上做以下调整即可完成功能,适配SwiftUI 3 + Xcode 13及以上版本要求:
第一步:给MapViewModel新增路线相关逻辑
在你现有的MapViewModel类中增加以下属性和方法:
class MapViewModel: NSObject, ObservableObject, CLLocationManagerDelegate { // 你原有已实现的属性保持不变 @Published var region = MKCoordinateRegion() // 新增属性:存储计算得到的路线 @Published var calculatedRoute: MKRoute? // 你原有已实现的checkLocationServicesIsEnabled等方法保持不变 // 新增方法:计算两点之间的路线 func fetchRoute(from start: CLLocationCoordinate2D, to end: CLLocationCoordinate2D, transportType: MKDirectionsTransportType = .automobile) { let startMark = MKPlacemark(coordinate: start) let endMark = MKPlacemark(coordinate: end) let routeRequest = MKDirections.Request() routeRequest.source = MKMapItem(placemark: startMark) routeRequest.destination = MKMapItem(placemark: endMark) routeRequest.transportType = transportType // 可选值:.walking步行/.transit公交/.automobile驾车 routeRequest.requestsAlternateRoutes = false // 不需要备选路线就设为false let directions = MKDirections(request: routeRequest) directions.calculate { [weak self] response, error in guard let self = self, let validResponse = response, error == nil else { // 可自行添加路线请求失败的异常处理 return } // 取第一条路线存储 self.calculatedRoute = validResponse.routes.first // 可选实现:自动调整地图区域,完整展示整条路线 if let routeRect = self.calculatedRoute?.polyline.boundingMapRect { self.region = MKCoordinateRegion(routeRect) } } } }
第二步:修改Map组件代码,增加路线渲染配置
Map(coordinateRegion: $mapViewModel.region, interactionModes: [.all], showsUserLocation: true, userTrackingMode: .constant(.none), // 新增:传入路线图层数据 overlayItems: mapViewModel.calculatedRoute != nil ? [mapViewModel.calculatedRoute!.polyline] : [], annotationItems: annotations) { place in MapAnnotation(coordinate: place.placemark.location!.coordinate) { MapPinView() } // 新增:路线渲染规则配置 } overlayContent: { overlayItem in if let polyline = overlayItem as? MKPolyline { MapPolyline(polyline) .stroke(.orange, lineWidth: 5) // 可自定义路线颜色、粗细 } } .tint(.blue) .environmentObject(mapViewModel) .edgesIgnoringSafeArea(.all) .onAppear { mapViewModel.checkLocationServicesIsEnabled() // 示例:触发路线计算,可替换为你实际需要的两个点位坐标 // 如果你需要用annotations数组里的点位,直接取对应元素的placemark.location!.coordinate即可 let pointA = CLLocationCoordinate2D(latitude: 39.9042, longitude: 116.4074) let pointB = CLLocationCoordinate2D(latitude: 39.9163, longitude: 116.3972) mapViewModel.fetchRoute(from: pointA, to: pointB) }
补充说明
- 如果需要展示多条备选路线,可以把
calculatedRoute属性改成@Published var calculatedRoutes: [MKRoute] = [],请求完成后赋值self.calculatedRoutes = response.routes,overlayItems参数传入calculatedRoutes.map{$0.polyline}即可 - 路线计算的触发时机可以根据业务需求调整,比如选中两个标注点后再调用
fetchRoute方法,不需要固定在onAppear中执行
内容的提问来源于stack exchange,提问作者Hatim
相关产品推荐
相关产品推荐

