Created
January 3, 2025 09:32
-
-
Save ankushkushwaha/552e9219e7cb143e6f2ef0ff1767cc9f to your computer and use it in GitHub Desktop.
MapKit marker following a route animation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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