refactor(route): show route in UIKit map when searched

This commit is contained in:
Oliver
2025-05-16 14:52:52 +02:00
parent 8ec74c1012
commit 171e181387
5 changed files with 49 additions and 17 deletions

View File

@@ -35,15 +35,6 @@ struct ContentView: View {
// if user clicks on the place, display better view and then calculate route there
var body: some View {
MapView(locationManager: locationManager, viewModel: viewModel)
// Map(position: $position) {
// UserAnnotation()
// ForEach(0..<directions.count) { i in
// if destination != nil {
// Marker(item: destination!)
// }
// MapPolyline(directions[i].polyline)
// .stroke(Defaults.routeColor[i], lineWidth: Defaults.routeWidth)
// }
.ignoresSafeArea()
.onAppear {
Task {

View File

@@ -43,6 +43,8 @@ struct SearchView: View {
.foregroundStyle(.gray)
.onTapGesture {
query = ""
viewModel.destination = nil
viewModel.directions = []
}
}
}

View File

@@ -8,12 +8,14 @@
import UIKit
import MapKit
import SwiftUI
import Combine
class UIKitMapView: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
var locationManager: LocationManager
var viewModel: ViewModel
var directions: [MKRoute] = []
var destination: MKMapItem?
var oldDirections: [MKRoute] = []
var oldDestination: MKMapItemAnnotation?
private var cancellables = Set<AnyCancellable>()
let mapView : MKMapView = {
let map = MKMapView()
map.showsUserTrackingButton = true
@@ -34,6 +36,7 @@ class UIKitMapView: UIViewController, MKMapViewDelegate, CLLocationManagerDelega
override func viewDidLoad() {
super.viewDidLoad()
bindViewModel()
mapView.delegate = self
setMapConstraints()
@@ -83,6 +86,42 @@ class UIKitMapView: UIViewController, MKMapViewDelegate, CLLocationManagerDelega
self.present(searchViewConctroller, animated: true, completion: nil)
}
private func refreshRoute() {
DispatchQueue.main.async {
for route in self.oldDirections {
self.mapView.removeOverlay(route.polyline)
}
self.oldDirections = self.viewModel.directions
for route in self.viewModel.directions {
self.mapView.addOverlay(route.polyline, level: .aboveRoads)
}
if let destination = self.oldDestination {
self.mapView.removeAnnotation(destination)
}
if let destination = self.viewModel.destination {
self.oldDestination = MKMapItemAnnotation(mapItem: destination)
self.mapView.addAnnotation(self.oldDestination!)
}
}
}
func mapView(_ mapView: MKMapView, rendererFor overlay: any MKOverlay) -> MKOverlayRenderer {
let renderer = MKGradientPolylineRenderer(overlay: overlay)
renderer.setColors(Defaults.routeColor, locations: [])
renderer.lineCap = .round
renderer.lineWidth = Defaults.routeWidth
return renderer
}
private func bindViewModel() {
viewModel.$directions
.receive(on: DispatchQueue.main)
.sink { [weak self] _ in
self?.refreshRoute()
}
.store(in: &cancellables)
}
}
struct MapView: UIViewControllerRepresentable {

View File

@@ -10,10 +10,10 @@ import MapKit
import SwiftUI
struct Defaults {
static let routeColor: [Color] = [
static let routeColor: [UIColor] = [
.blue,
.red,
.yellow,
// .red,
// .yellow,
]
static let routeWidth: CGFloat = 8