hulab / ClusterKit

An iOS map clustering framework targeting MapKit, Google Maps and Mapbox.
MIT License
512 stars 86 forks source link

Number of annotations inside a cluster change without animations #7

Open ghost opened 7 years ago

ghost commented 7 years ago

Hello !

So I've worked with this framework for swift with MKMapView, and I'm using a system where I show the number of annotations inside a cluster. The issue I've found is that if we have 2 nearby clusters and the algorithm recalculates such that one annotation moves from one cluster to the other, no animation will occur and the change is instant.

This issue isn't really apparent in the examples provided because it doesn't show how many annotations are inside a cluster, but if you use this code you can see it:

    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {

        let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: "annotation") ??
            newAnnotationView(forAnnotation: annotation)

        if let cluster = annotation as? CKCluster {
            let label = annotationView.viewWithTag(1235) as! UILabel

            if cluster.count > 1 {
                annotationView.canShowCallout = false
                annotationView.image = UIImage(named: "cluster")

                label.text = "\(cluster.count)"
                label.isHidden = false
            } else {
                label.isHidden = true
                annotationView.canShowCallout = true
                annotationView.image = UIImage(named: "marker")
            }
        }
        return annotationView;
    }

    private func newAnnotationView(forAnnotation annotation: MKAnnotation) -> MKAnnotationView {
        let annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: "annotation")
        let centerText = UILabel()
        centerText.translatesAutoresizingMaskIntoConstraints = false
        centerText.tag = 1235
        centerText.textColor = UIColor.cyan
        annotationView.addSubview(centerText)

        annotationView.addConstraint(NSLayoutConstraint(item: centerText, attribute: NSLayoutAttribute.centerX, relatedBy: NSLayoutRelation.equal, toItem: annotationView, attribute: NSLayoutAttribute.centerX, multiplier: 1, constant: 0))
        annotationView.addConstraint(NSLayoutConstraint(item: centerText, attribute: NSLayoutAttribute.centerY, relatedBy: NSLayoutRelation.equal, toItem: annotationView, attribute: NSLayoutAttribute.centerY, multiplier: 1, constant: 0))

        return annotationView
    }

Find a location and zoom in slightly or zoom out slightly and you will notice that some clusters change the amount of annotations even though nothing goes in or out of them.

maxep commented 6 years ago

This is due to the conditions of animations:

These conditions are simple in order to have good animation performances (even if it could be better). I could think of a more sophisticated conditions, like using a cluster bounds or an array intersection.

ghost commented 6 years ago

You don't need to replace it entirely, just give the option to choose between the two, like with the algorithms. I'm willing to sacrifice performance in certain scenarios.