3

I can get an annotationView from an MKMapView by simply passing it an annotation:

view(for annotation: MKAnnotation) -> MKAnnotationView?

That returns an optional, because if an annotation is offscreen, it might not have an associated annotationView.

Is there a reliable way to always retrieve an MKAnnotationView for a given MKAnnotation?

I've even tried manually calling MKMapView's delegate, but it crashes my app with a vague message:

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
    if annotation is MKUserLocation {
        return nil
    }

    return MKPinAnnotationView(annotation: annotation, reuseIdentifier: nil)
}

Use case:

I'm developing a custom VoiceOver rotor that will allow users to navigate from one pin to another by flicking the screen. So if there's 1 pin on each continent, they can flick up or down and the map will center over that pin without having to pan the map. The difficulty is I need to tell the custom rotor where to go, but if an annotation is way offscreen, there's no annotationView associated with it yet, so I can't instruct the rotor properly.

djibouti33
  • 12,102
  • 9
  • 83
  • 116

1 Answers1

2

In my situation, I not only needed the MKAnnotationView, but I also needed to center the map over the annotation, so this worked for me:

// imperative that this is called without animation.
// setCenter will trigger the delegate method mapView(_:viewFor:) immediately
self.mapView.setCenter(requestedAnnotation.coordinate, animated: false)

// by the time we need the view, there's one associated with the annotation
if let annotationView = self.mapView.view(for: requestedAnnotation) {
  // we have an annotationView
}
djibouti33
  • 12,102
  • 9
  • 83
  • 116