David Lintin David Lintin - 1 month ago 15
Swift Question

Removing Annotation using the Annotations Coordinates

I am using Firebase to get annotations on to mapView. This is done through the following:

func getMarkers() {

dbRef.observe(.value, with: { (snapshot) in

for buildings in snapshot.children {

let buildingsObject = Buildings (snapshot: buildings as! FIRDataSnapshot)

let latDouble = Double(buildingsObject.latitude!)
let lonDouble = Double(buildingsObject.longitude!)

self.telephoneNumber = buildingsObject.number

let annotation = myAnnotationView.init(title: buildingsObject.content!, coordinate: CLLocationCoordinate2D.init(latitude: latDouble!, longitude: lonDouble!), duration: buildingsObject.duration!, cost: buildingsObject.cost!, info: "", timestamp: buildingsObject.timestamp, contactNumber: buildingsObject.number!, addedBy: buildingsObject.addedByUser!)

self.mapView.addAnnotation(annotation)

print (snapshot)

}})}


myAnnotationView is my custom class for the AnnotationView.

adding Annotations to the map no problem. The issue arrises where if the user needs to remove his annotation it needs to be removed from the mapView. I have a table with all the users annotations in where he can delete if they so choose. This updates to firebase console and the data is removed. However, the annotation is still on the map and only when you reset the app the annotation will update.

I have a method to observe the deletedChilds which im getting a correct snapshot of but I cant seem to reference the annotation which needs to be removed.

func removeMarkers() {

dbRef.observe(.childRemoved, with: { (snapshot) in

print (snapshot)

})}


the snapshot being spat out is here:

Snap (-KTo3kdGGA_-rfUhHVnK) { //childByAutoID
addedByUser = TzDyIOXukcVYFr8HEBC5Y9KeOyJ2;
content = "Post";
cost = 500;
duration = Monthly;
latitude = "25.0879112000924";
longitude = "55.1467777484226";
number = 1234567890;
timestamp = "Tue 11 Oct";
}


So my question is how can I remove the annotation which is in this snapshot? Can I somehow reference its coordinates and removeAnnotation that way? I have looked through Stack but its mostly mentioning how to remove all annotations.

Many thanks. D

Answer

MapKit has removeAnnotation method, that can be used remove a specific annotation.

In your case you need to a way to compare coordinates. WE can do that using an extension on CLLocationCoordinate2D

extension CLLocationCoordinate2D: Hashable {
    public var hashValue: Int {
        get {
            // Add the hash value of lat and long, taking care of overlfolow. Here we are muliplying by an aribtrary number. Just in case.
            let latHash = latitude.hashValue&*123
            let longHash = longitude.hashValue
            return latHash &+ longHash
        }
    }
}

// Conform to the Equatable protocol.
public func ==(lhs: CLLocationCoordinate2D, rhs: CLLocationCoordinate2D) -> Bool {
    return lhs.latitude == rhs.latitude && lhs.longitude == rhs.longitude
}

Now, you can fetch all the annotations from the map, can check if any matches your co-ordinate & remove it.

        let allAnnotations = self.mapView.annotations
        for eachAnnot in allAnnotations{
            if eachAnnot.coordinate == <Your Coordinate>{
                self.mapView.removeAnnotation(eachAnnot)
            }
        }