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

@@ -15,7 +15,7 @@ struct ContentView: View {
@StateObject var locationManager = LocationManager() @StateObject var locationManager = LocationManager()
@StateObject var healthKitManager = HealthKitManager() @StateObject var healthKitManager = HealthKitManager()
// TODO: create a map // TODO: create a map
// Add navigation to the map // Add navigation to the map
// after you click the navigation button, show the start and end place on the map with a tag or whatever it's called // after you click the navigation button, show the start and end place on the map with a tag or whatever it's called
@@ -28,22 +28,13 @@ struct ContentView: View {
// Add favorite locations - like home, work, etc (probably should be stored in core data tho:/) // Add favorite locations - like home, work, etc (probably should be stored in core data tho:/)
// FIX: search is bad lol // FIX: search is bad lol
// How to speed up? // How to speed up?
// calculate only the distance between the start and end instead of getting directions for everything // calculate only the distance between the start and end instead of getting directions for everything
// if user clicks on the place, display better view and then calculate route there // if user clicks on the place, display better view and then calculate route there
var body: some View { var body: some View {
MapView(locationManager: locationManager, viewModel: viewModel) 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() .ignoresSafeArea()
.onAppear { .onAppear {
Task { Task {
@@ -59,7 +50,7 @@ struct ContentView: View {
} }
return nil return nil
} }
func save(value: String) { func save(value: String) {
viewModel.saveValue(value) viewModel.saveValue(value)
} }

View File

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

View File

@@ -8,12 +8,14 @@
import UIKit import UIKit
import MapKit import MapKit
import SwiftUI import SwiftUI
import Combine
class UIKitMapView: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate { class UIKitMapView: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
var locationManager: LocationManager var locationManager: LocationManager
var viewModel: ViewModel var viewModel: ViewModel
var directions: [MKRoute] = [] var oldDirections: [MKRoute] = []
var destination: MKMapItem? var oldDestination: MKMapItemAnnotation?
private var cancellables = Set<AnyCancellable>()
let mapView : MKMapView = { let mapView : MKMapView = {
let map = MKMapView() let map = MKMapView()
map.showsUserTrackingButton = true map.showsUserTrackingButton = true
@@ -34,6 +36,7 @@ class UIKitMapView: UIViewController, MKMapViewDelegate, CLLocationManagerDelega
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
bindViewModel()
mapView.delegate = self mapView.delegate = self
setMapConstraints() setMapConstraints()
@@ -83,6 +86,42 @@ class UIKitMapView: UIViewController, MKMapViewDelegate, CLLocationManagerDelega
self.present(searchViewConctroller, animated: true, completion: nil) 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 { struct MapView: UIViewControllerRepresentable {

View File

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