Skip to content

Instantly share code, notes, and snippets.

@ankushkushwaha
Created January 3, 2025 09:32
Show Gist options
  • Save ankushkushwaha/552e9219e7cb143e6f2ef0ff1767cc9f to your computer and use it in GitHub Desktop.
Save ankushkushwaha/552e9219e7cb143e6f2ef0ff1767cc9f to your computer and use it in GitHub Desktop.
MapKit marker following a route animation
import SwiftUI
import MapKit
struct MapKitView: View {
@State private var selectedResult: MKMapItem?
@State private var route: MKRoute?
@State private var markerCoordinate: CLLocationCoordinate2D
@State private var timer: Timer?
@State private var pathCoordinates: [CLLocationCoordinate2D] = []
@State private var currentIndex: Int = 0
private let startingPoint = CLLocationCoordinate2D(
latitude: 40.83657722488077,
longitude: 14.306896671048852
)
private let destinationCoordinates = CLLocationCoordinate2D(
latitude: 40.849761,
longitude: 14.263364
)
init() {
markerCoordinate = startingPoint
}
var body: some View {
Map(selection: $selectedResult) {
// Adding the marker for the current position
Marker("Moving", coordinate: markerCoordinate)
// Show the route if it is available
if let route {
MapPolyline(route)
.stroke(.blue, lineWidth: 5)
}
}
.onChange(of: selectedResult) {
getDirections()
}
.onAppear {
self.markerCoordinate = startingPoint
self.selectedResult = MKMapItem(placemark: MKPlacemark(coordinate: self.destinationCoordinates))
}
}
func getDirections() {
self.route = nil
// Check if there is a selected result
guard let selectedResult else { return }
// Create and configure the request
let request = MKDirections.Request()
request.source = MKMapItem(placemark: MKPlacemark(coordinate: self.startingPoint))
request.destination = self.selectedResult
// Get the directions based on the request
Task {
let directions = MKDirections(request: request)
let response = try? await directions.calculate()
route = response?.routes.first
if let polyline = route?.polyline {
extractCoordinates(from: polyline)
animateMarker()
}
}
}
func extractCoordinates(from polyline: MKPolyline) {
pathCoordinates = []
for i in 0..<polyline.pointCount {
let point = polyline.points()[i]
pathCoordinates.append(CLLocationCoordinate2D(latitude: point.coordinate.latitude, longitude: point.coordinate.longitude))
}
}
func animateMarker() {
timer?.invalidate()
currentIndex = 0
timer = Timer.scheduledTimer(withTimeInterval: 0.05, repeats: true) { _ in
guard currentIndex < pathCoordinates.count else {
timer?.invalidate()
return
}
markerCoordinate = pathCoordinates[currentIndex]
currentIndex += 1
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment