Search code examples
iosobjective-cmapkitmkannotationmkannotationview

Modify existing MKAnnotationView


I have a MapKit view with a large number of default MKAnnotationView pins. I would like to modify an existing pin (i.e. one that's been on the view for a while, not during initial appearance). When the underlying data for a location changes I'd like to change its subtitle, and give it a small animation (jiggle or similar).

While I see my MKAnnotationView's, they do not appear to have superview's. For example:

for (MKAnnotationView *annotationView in self.mapView.annotations) {
    if (annotationView.superview) {
        NSLog(@"Hooray!");
    }
}

While I have many annotations (I see them, plus I've seen them in the debugger here), none have a superView.

Is this doable? Or will I need to implement a custom view for this purpose?


Solution

  • The mapView.annotations is an array of annotations, not of annotation views. I'm a little surprised that it didn't crash when you tried calling the superview method on the annotation.

    To get the annotation view, it is

    MKPinAnnotationView *annotationView = (id)[mapView viewForAnnotation:annotation];
    if (annotationView) {
        // annotation view for this annotation is available
    }
    

    I'm unclear why you need the superview for the annotation view, though. Personally, I'd be hesitant to mess around in the map view's internal view hierarchy.

    If I wanted to animate the changing of the color, I might do something like:

    MKPinAnnotationView *visibleAnnotationView = (id)[mapView viewForAnnotation:annotation];
    if (visibleAnnotationView) {
        [UIView transitionWithView:visibleAnnotationView duration:0.25 options:UIViewAnimationOptionTransitionFlipFromRight animations:^{
            visibleAnnotationView.pinTintColor = [UIColor blueColor];
        } completion:nil];
    }
    

    Obviously, do whatever animation you want, but hopefully this illustrates the idea.

    Note, though, that the situation is actually a little more complicated than this, because if the user pans the annotation view off screen and then back on, your MKMapViewDelegate method mapView:viewForAnnotation: would have to know what type of annotation view to return. So you'd probably end up wanting to have a custom MKAnnotation subclass with whatever state information you need so that mapView:viewForAnnotation: could act accordingly.