3

I am trying to use a custom image on my MKAnnotationView when I use the following code I get no image on my annotation. I have checked in debug to ensure the image is being properly loaded into the UIImage.

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {


    MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:@"String"];
    if(!annotationView) {

        annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"String"];
        UIButton *directionButton = [UIButton buttonWithType:UIButtonTypeCustom];
        UIImage *directionIcon = [UIImage imageNamed:@"IconDirections"];

        [directionButton setImage:directionIcon forState:UIControlStateNormal];

        annotationView.rightCalloutAccessoryView = directionButton;
    }

    annotationView.enabled = YES;
    annotationView.canShowCallout = YES;

    return annotationView;
}
Clip
  • 3,018
  • 8
  • 42
  • 77

2 Answers2

8

There are two main issues:

  1. The frame of the custom callout button is not set making it essentially invisible.
  2. An MKAnnotationView is being created but its image property (the image of the annotation itself -- not the callout button's) is not set. This makes the whole annotation invisible.

For issue 1, set the button's frame to some appropriate value. For example:

UIImage *directionIcon = [UIImage imageNamed:@"IconDirections"];
directionButton.frame = 
    CGRectMake(0, 0, directionIcon.size.width, directionIcon.size.height);

For issue 2, set the annotation view's image (or create an MKPinAnnotationView instead):

annotationView.image = [UIImage imageNamed:@"SomeIcon"];


Additionally, you should handle view re-use correctly by updating the annotation property.
Complete example:

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation 
{    
    MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:@"String"];
    if(!annotationView) {

        annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"String"];

        annotationView.image = [UIImage imageNamed:@"SomeIcon"];

        UIButton *directionButton = [UIButton buttonWithType:UIButtonTypeCustom];
        UIImage *directionIcon = [UIImage imageNamed:@"IconDirections"];
        directionButton.frame = 
            CGRectMake(0, 0, directionIcon.size.width, directionIcon.size.height);

        [directionButton setImage:directionIcon forState:UIControlStateNormal];

        annotationView.rightCalloutAccessoryView = directionButton;
        annotationView.enabled = YES;
        annotationView.canShowCallout = YES;
    }
    else {
        //update annotation to current if re-using a view
        annotationView.annotation = annotation;
    }    

    return annotationView;
}
0

In order for the callout to be shown, the annotation must be selected. To do this programmatically, call:

[mapView selectAnnotation:annotation animated:YES];

where annotation is the specific MKAnnotation for which you want a callout displayed.

You'll almost certainly want to put this in - (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views.

There are a few caveats to consider, so here are two other posts that have some great answers and relevant discussions:

Community
  • 1
  • 1
nklauza
  • 1,501
  • 1
  • 12
  • 12