I'm trying to register custom annotation views (I create them as a subclass of MKAnnotationView), but I have some trouble with that. Initially, I've tried to register only one custom annotation view for a single annotation marker using the code below (RestaurantMarkerView is my custom annotation view):
mapView.register(RestaurantMarkerView.self, forAnnotationViewWithReuseIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier)
It works fine (when I tap the pin, it shows the callout). Now I add another annotation marker and try to register another view for it, and as far as I know, in that case I should use custom identifiers for the views, so I do that by this code:
mapView.register(RestaurantMarkerView.self, forAnnotationViewWithReuseIdentifier: "a")
mapView.register(ChoosenRestaurantMarkerView.self, forAnnotationViewWithReuseIdentifier: "b")
Now when I tap the markers, they don't show callouts. When I change the reuse identifier of one of the markers to MKMapViewDefaultAnnotationViewReuseIdentifier
, that marker shows the callout. So, how can I register multiple custom annotation views? Thanks.
As @Paulw says, you will need to implement the MKMapViewDelegate
function mapView(_:viewFor:)
to return the appropriate view.
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if annotation is MKUserLocation {
return nil
}
if /* condition */ {
let reuseId = "a"
var pinView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseId)
if pinView == nil {
pinView = RestaurantMarkerView(annotation: annotation, reuseIdentifier: reuseId)
pinView?.canShowCallout = true
} else {
pinView?.annotation = annotation
}
return pinView
} else {
let reuseId = "b"
var pinView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseId)
if pinView == nil {
pinView = ChoosenRestaurantMarkerView(annotation: annotation, reuseIdentifier: reuseId)
pinView?.canShowCallout = true
} else {
pinView?.annotation = annotation
}
return pinView
}
}
The accepted answer was correct usage for pre-iOS11, before mapView.register(, forAnnotationViewWithReuseIdentifier:)
became available, and it is still allowed for iOS11+, but the answer is incorrect for the question that is asked.
See Apple's map annotation clustering example app, downloadable from the docs: https://developer.apple.com/documentation/mapkit/mkannotationview/decluttering_a_map_with_mapkit_annotation_clustering
You should register all of your annotation exactly as you did in the first part of the question:
mapView.register(UnicycleAnnotationView.self, forAnnotationViewWithReuseIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier)
mapView.register(BicycleAnnotationView.self, forAnnotationViewWithReuseIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier)
mapView.register(TricycleAnnotationView.self, forAnnotationViewWithReuseIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier)
It will automatically generate the actual reuseIdentifier based on the name of the class that you are registering.
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