Finding Custom AnnotationViews with MKMapView


If you've subclassed MKAnnotationViews and created your own custom MKAnnotation then you'll find yourself writing a lot of code like this:

if let userAnnotationView = mapView.viewForAnnotation(myCustomAnnotation) as? UserAnnotationView {
    //do something with the annotation view

This is quite undesireable, and you know what this means! We can write a nice extension method for it using generics.

We created an extension method that helps wrangle the type of the class on the way in and out.

import MapKit
extension MKMapView {
    func annotationViewForAnnotation<T: MKAnnotationView>(type: T.Type, annotation: MKAnnotation?) -> T? {
        guard let annotation = annotation else { return nil }
        if let annotationView = self.viewForAnnotation(annotation) as? T {
            return annotationView
        return nil

So the way we use this is quite simple:

var myAnnotation: MKAnnotation = getItFromSomeWhere();
var foundAnnotationView = mapView.annotationViewForAnnotation(UserAnnotationView.self, myAnnotation);

if annotationView == nil {
    print("MKMapView Instance has an annotation")
    print("MKMapView Instance doesn't have an annotationView instance")

Remember because of the nature of MKMapView, which operates quite closely to UITableView or UICollectionView, the annotationView can be nil! For example, you may have an annotation centered in Dubai but your map is focused primarily around San Franscisco. Just because you've alled mapView.addAnnotation(myDubaiAnnotation) Doesn't mean that the mapView will render anything at all.

So you will have to check if the annotationView is available at all for mutation.


Maximilian Alexander