How to cluster annotations in MapKit in iOS 11

Issue #181

https://developer.apple.com/documentation/mapkit/mkannotationview/decluttering_a_map_with_mapkit_annotation_clustering

1
2
3
4
5
6
7
8
9
10
11
final class AnnotationView: MKMarkerAnnotationView {
override init(annotation: MKAnnotation?, reuseIdentifier: String?) {
super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)

clusteringIdentifier = String(describing: ClusterView.self)
}

required init?(coder aDecoder: NSCoder) {
fatalError()
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
final class ClusterView: MKAnnotationView {
override init(annotation: MKAnnotation?, reuseIdentifier: String?) {
super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
displayPriority = .defaultHigh
}

required init?(coder aDecoder: NSCoder) {
fatalError()
}

override func prepareForDisplay() {
super.prepareForDisplay()

guard let annotation = annotation as? MKClusterAnnotation else {
return
}

let count = annotation.memberAnnotations.count
image = self.image(annotation: annotation, count: count)
}

func image(annotation: MKClusterAnnotation, count: Int) -> UIImage? {
let renderer = UIGraphicsImageRenderer(size: CGSize(width: 40.0, height: 40.0))
image = renderer.image { _ in
UIColor.purple.setFill()
UIBezierPath(ovalIn: CGRect(x: 0.0, y: 0.0, width: 40.0, height: 40.0)).fill()
let attributes: [NSAttributedString.Key: Any] = [
NSAttributedString.Key.foregroundColor: UIColor.white,
NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 20.0)
]

let text = "\(count)"
let size = text.size(withAttributes: attributes)
let rect = CGRect(x: 20 - size.width / 2, y: 20 - size.height / 2, width: size.width, height: size.height)
text.draw(in: rect, withAttributes: attributes)
}

return image
}
}
1
mapView.register(ClusterView.self, forAnnotationViewWithReuseIdentifier: String(describing: ClusterView.self))

Comments