Search code examples
swiftmkmapview

check if MKMarkerAnnotationView is cluttered or decluttered in MKMapView


I have done Clustering for Points by referencing the below example provided by apple. https://developer.apple.com/documentation/mapkit/mkannotationview/decluttering_a_map_with_mapkit_annotation_clustering

I wanted to know wether there is any method which gets called when the annotations are cluttered & decluttered.

Or

How I can come to know that particular annotation is cluttered and decluttered as I need to run some code block for that.


Solution

  • How I can come to know that particular annotation is cluttered and decluttered.

    Check within MKClusterAnnotation.memberAnnotations if a MKAnnotation is present, like so:

    func isCluttered(annotation: MKAnnotation) -> Bool {
        let clusters = mapView.annotations.filter({ $0 is MKClusterAnnotation }) as! [MKClusterAnnotation]
        for cluster in clusters {
            if cluster.memberAnnotations.first(where: { $0 === annotation }) != nil {
                return true
            }
        }
        return false
    }
    

    Usage: picks a random annotation from mapView

    let annotations = mapView.annotations.filter { $0 is Cycle }
    let randomIndex = Int(arc4random_uniform(UInt32(annotations.count)))
    if (isCluttered(annotation: annotations[randomIndex])) {
        print("Cluttered")
    } else {
        print("Not cluttered")
        mapView.selectAnnotation(annotations[randomIndex], animated: true)
    }
    

    check if MKMarkerAnnotationView is cluttered or decluttered in MKMapView

    MKMarkerAnnotationView is a subclass of MKAnnotationView, and you can override setSelected(_:animated:), for an example open ClusterAnnotationView.swift from your linked sample code and paste this:

    override func setSelected(_ selected: Bool, animated: Bool) {
        let cluster = annotation as? MKClusterAnnotation
        print("\(selected ? "Selecting" : "Deselected") Clustered Annotation \(cluster?.memberAnnotations.count ?? -1)")
    }
    

    Similarly you can override the setSelected(_:animated:) method in each MKMarkerAnnotationView in CycleAnnotationView.swift, paste in all 3 classes:

    override func setSelected(_ selected: Bool, animated: Bool) {
        print("\(selected ? "Selecting" : "Deselected") unclustered annotation with type: \(clusteringIdentifier!)")
    }
    

    Now run and tap annotations on map and check Debug area for print messages.