If you need to display many annotations in your MKMapView
it is recommended to cluster them for better performance.
Map clustering
This means instead of showing all the visible annotations you group annotations that are close together into one single annotation cluster representing them instead.
This cluster annotation usually shows the number of annotations it represents. As you then zoom in to get finer detail the clusters break up and show the actual annotations.

Clustering is supported in MKMapView
on iOS 11 and newer, no need to use any custom library. If you need to support older versions of iOS, there are libraries like Cluster that you can use.
Custom cluster view implementation
Let’s say you use a custom annotation view to show your annotations and you want to add support for clustering. You first create a custom MKAnnotationView
in the same way
final class LocationDataMapClusterView: MKAnnotationView {
// MARK: Initialization
private let countLabel = UILabel()
override var annotation: MKAnnotation? {
didSet {
guard let annotation = annotation as? MKClusterAnnotation else {
assertionFailure("Using LocationDataMapClusterView with wrong annotation type")
return
}
countLabel.text = annotation.memberAnnotations.count < 100 ? "\(annotation.memberAnnotations.count)" : "99+"
}
}
override init(annotation: MKAnnotation?, reuseIdentifier: String?) {
super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
displayPriority = .defaultHigh
collisionMode = .circle
frame = CGRect(x: 0, y: 0, width: 40, height: 50)
centerOffset = CGPoint(x: 0, y: -frame.size.height / 2)
setupUI()
}
@available(*, unavailable)
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
// MARK: Setup
private func setupUI() {
...
}
}
The idea is the same as when custom annotation view, but there is a difference. You need to define displayPriority
to tell the map that your cluster annotation has a higher priority that normal annotation.