ios - With SwiftUI, add great amount of annotations to MKMapView - Slsolutech Best IT Related Website google.com, pub-5682244022170090, DIRECT, f08c47fec0942fa0

ios – With SwiftUI, add great amount of annotations to MKMapView

Spread the love


With SwiftUI, I add 5 000 annotations to MKMapView. When the map is moved round, zoomed in or out, the app is lagging.

What I’ve completed to extend efficiency is:

  • Set .clusteringIdentifier on MKMarkerAnnotationView
  • Set reuseIdentifier on MKMarkerAnnotationView
  • Dequeue MKMarkerAnnotationView for reuse

Can I get an app that does not lag?

This can be a minimal reproducible instance:

MapView.swift

import SwiftUI
import MapKit

struct MapView: UIViewRepresentable {
    
    let locationManager = CLLocationManager()
    let mapView: MKMapView = MKMapView(body: .zero)
    
    func makeCoordinator() -> MapViewCoordinator{
        MapViewCoordinator(self)
    }
    
    func makeUIView(context: Context) -> MKMapView {
        mapView.register(MKMarkerAnnotationView.self, forAnnotationViewWithReuseIdentifier: MapViewCoordinator.clusterReuseId)
        mapView.register(CustomMKMarkerAnnotationView.self, forAnnotationViewWithReuseIdentifier: CustomMKMarkerAnnotationView.ReuseId)
        mapView.delegate = context.coordinator
        
        var annotations = [MKPointAnnotation]()
        for _ in 0...5000 {
            let annotation = MKPointAnnotation()
            annotation.title = "Take a look at"
            annotation.coordinate = CLLocationCoordinate2D(latitude: Double.random(in: 50...52), longitude: Double.random(in: 0...2))
            annotations.append(annotation)
        }
        mapView.addAnnotations(annotations)
        
        return mapView
    }
    
    func updateUIView(_ uiView: MKMapView, context: UIViewRepresentableContext<MapView>) {
    }
}

MapViewCoordinator.swift

import Basis
import MapKit

class MapViewCoordinator: NSObject, MKMapViewDelegate {
    var mapViewController: MapView
    static let clusterReuseId = "cluster"
    
    init(_ management: MapView) {
        self.mapViewController = management
    }
    
    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
        if (annotation is MKUserLocation) { return nil }
        
        if let cluster = annotation as? MKClusterAnnotation {
            let markerAnnotationView: MKMarkerAnnotationView
            if let dequeued = mapView.dequeueReusableAnnotationView(withIdentifier: Self.clusterReuseId, for: cluster) as? MKMarkerAnnotationView {
                markerAnnotationView = dequeued
                markerAnnotationView.annotation = cluster
            } else {
                markerAnnotationView = MKMarkerAnnotationView(annotation: cluster, reuseIdentifier: Self.clusterReuseId)
            }
            markerAnnotationView.glyphText = String(cluster.memberAnnotations.rely)
            markerAnnotationView.markerTintColor = UIColor.systemBlue
            markerAnnotationView.canShowCallout = false
            return markerAnnotationView
        }
        
        let annotationView: CustomMKMarkerAnnotationView
        guard let annotation = annotation as? MKPointAnnotation else { return nil }
        
        if let dequeuedView = mapView.dequeueReusableAnnotationView(
            withIdentifier: CustomMKMarkerAnnotationView.ReuseId) as? CustomMKMarkerAnnotationView
        {
            annotationView = dequeuedView
            annotationView.annotation = annotation
        }
        else
        {
            annotationView = CustomMKMarkerAnnotationView(annotation: annotation, reuseIdentifier: CustomMKMarkerAnnotationView.ReuseId)
        }
                
        annotationView.clusteringIdentifier = CustomMKMarkerAnnotationView.ReuseId
        return annotationView
    }
}

CustomMKMarkerAnnotationView.swift

import MapKit

let clusterId = "clusterId"

class CustomMKMarkerAnnotationView: MKMarkerAnnotationView {
    
    static let ReuseId = "customAnnotation"
    
    override init(annotation: MKAnnotation?, reuseIdentifier: String?) {
        tremendous.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
        clusteringIdentifier = clusterId
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been carried out")
    }
    
    override func prepareForDisplay() {
        tremendous.prepareForDisplay()
    }
}

Leave a Reply

Your email address will not be published. Required fields are marked *