Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Update Annotation Coordinates on MapView

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
    }
like image 521
Emirhan Karahan Avatar asked Nov 28 '25 18:11

Emirhan Karahan


1 Answers

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()
    }
}
like image 59
Emirhan Karahan Avatar answered Nov 30 '25 07:11

Emirhan Karahan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!