After implementing a way to cluster customised annotations, the application crashes whenever the view of the map is adjusted rapidly, by scrolling or changing the zoom-level.
-[MKPointAnnotation memberAnnotations]: unrecognized selector sent to instance 0x281396c00
My guess is that the compiler is trying to retrieve the annotation information, but cannot find the data. As I'm fairly new to Swift, I don't see what I'm missing. Your help would be greatly appreciated.
I have a pretty basic setup to display the map in SwiftUI. In the main file, I call the MapView from MapView.swift
struct MapView: UIViewRepresentable {
@ObservedObject var store = DataStoreMap()
func makeCoordinator() -> MapViewCoordinator {
MapViewCoordinator(self)
}
func makeUIView(context: Context) -> MKMapView{
MKMapView(frame: .zero)
}
func updateUIView(_ view: MKMapView, context: Context){
let location = getUserLocation()
let chargers = store.chargers
let coordinate = CLLocationCoordinate2D(latitude: location.latitude, longitude: location.longitude)
let span = MKCoordinateSpan(latitudeDelta: 0.03, longitudeDelta: 0.03)
let region = MKCoordinateRegion(center: coordinate, span: span)
view.setRegion(region, animated: true)
for charger in chargers {
let annotation = MKPointAnnotation()
annotation.coordinate = CLLocationCoordinate2D(latitude: charger.addressInfo.latitude, longitude: charger.addressInfo.longitude)
view.delegate = context.coordinator
view.addAnnotation(annotation)
}
}
}
Also included in the same file is my custom annotation class.
class MapViewCoordinator: NSObject, MKMapViewDelegate {
var mapViewController: MapView
init(_ control: MapView) {
self.mapViewController = control
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
//Custom View for Annotation
var annotationView = MKMarkerAnnotationView()
annotationView.canShowCallout = true
let identifier = "laadpaal"
if let dequedView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? MKMarkerAnnotationView {
annotationView = dequedView
} else {
annotationView = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: identifier)
}
annotationView.markerTintColor = .some(.systemBlue)
annotationView.glyphImage = UIImage(named: "car1")
annotationView.glyphTintColor = .yellow
annotationView.clusteringIdentifier = identifier
return annotationView
}
}
The cause for your crash is that you don't account for other annotations requested by map kit (e.g. MKUserLocation). You are triggering this due to the automatic clustering as you set clusteringIdentifier to a non-nil value.
Just return nil when you want to deal with the annotation yourself so MKMapView uses the default handling:
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if annotation is MKUserLocation { return nil }
if annotation is MKClusterAnnotation { return nil }
let view = mapView.dequeueReusableAnnotationView(withIdentifier: "identifier", for: annotation)
view.clusteringIdentifier = "clusterIdentifer"
// …
return view
}
If you ever want to customize the cluster annotations just add a special case for MKClusterAnnotation. And if you show user location don't forget to return nil for MKUserLocation if you want the default blue dot.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With