I have a mapView and vehicle coordinates which changes in every 15 seconds so I want to update the coordinates. My current approach is to delete all annotations and adding new ones. However, I can't use animations in that approach, they are just spawning. When I looked google I've found out that people just changing the coordinates of annotations and it's happening. Not for me unfortunately.
Old version:
func updateVehicleLocations(){
let annotations = mapView.annotations.filter {
$0.title != "person"
}
mapView.removeAnnotations(annotations)
for vehicle in vehicles {
let pin = MKPointAnnotation()
pin.coordinate = CLLocationCoordinate2D(latitude: vehicle.latitude, longitude: vehicle.longitude)
pin.title = vehicle.vehicleID
mapView.addAnnotation(pin)
}
if isSetCoordinatesMoreThanOnce { return }
mapView.showAnnotations(mapView.annotations, animated: true)
isSetCoordinatesMoreThanOnce = true
}
My test:
func updateVehicleLocations(){
for annotation in busAnnotations {
UIView.animate(withDuration: 0.5) { [self] in
if let vehicle = self.vehicles.first(where: { $0.vehicleID == annotation.vehicleID }) {
annotation.coordinate = CLLocationCoordinate2D(latitude: vehicle.latitude, longitude: vehicle.longitude)
}
}
}
if isSetCoordinatesMoreThanOnce { return }
for vehicle in vehicles {
let pin = BusAnnotation(coordinate: CLLocationCoordinate2D(latitude: vehicle.latitude, longitude: vehicle.longitude), vehicleID: vehicle.vehicleID)
busAnnotations.append(pin)
}
mapView.addAnnotations(busAnnotations)
mapView.showAnnotations(mapView.annotations, animated: true)
isSetCoordinatesMoreThanOnce = true
}
That was exhausting, I still don't get the logic but here is how I fixed it;
I had to use a custom class(of MKAnnotation) to set coordinates otherwise the coordinate property is read-only. So, here is an example custom annotation class;
final class BusAnnotation: NSObject, MKAnnotation{
var vehicleID: String
var coordinate: CLLocationCoordinate2D
init(coordinate: CLLocationCoordinate2D, vehicleID:String) {
self.coordinate = coordinate
self.vehicleID = vehicleID
super.init()
}
}
however, it doesn't update coordinates, to fix it we need to add "dynamic" keyword to coordinate property everything works fine!
final class BusAnnotation: NSObject, MKAnnotation{
var vehicleID: String
dynamic var coordinate: CLLocationCoordinate2D
init(coordinate: CLLocationCoordinate2D, vehicleID:String) {
self.coordinate = coordinate
self.vehicleID = vehicleID
super.init()
}
}