0
votes

I am adding some annotations to a MKMapView and these annotations have a UIImageView, loaded asynchronously with AFNetworking, as left callout accessory view. Here's the implementation:

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
    static NSString *identifier = @"MapAnnotation";

    if ([annotation isKindOfClass:[MapAnnotation class]]) {

        MKAnnotationView *annotationView = (MKAnnotationView *)[_mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
        if (annotationView == nil) {
            annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
            annotationView.enabled = YES;
            annotationView.canShowCallout = YES;
            annotationView.image = [UIImage imageNamed:@"map_pin"];

            UIImageView *userAvatar = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];
            [userAvatar setImageWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"https://graph.facebook.com/%@/picture?type=small",[[(MapAnnotation *)annotation user] facebookID]]] placeholderImage:[UIImage imageNamed:@"user_placeholder"]];
            userAvatar.layer.cornerRadius = 4.0;
            userAvatar.layer.masksToBounds = YES;
            userAvatar.layer.borderColor = [[UIColor blackColor] CGColor];
            userAvatar.layer.borderWidth = 1;

            annotationView.leftCalloutAccessoryView = userAvatar;

            UIButton *rightCallout = [UIButton buttonWithType:UIButtonTypeInfoLight];

            annotationView.rightCalloutAccessoryView = rightCallout;

        }

        annotationView.annotation = annotation;

        return annotationView;
    }

    return nil;
}

The problem here is: sometimes (not all the times) when annotations for different users are loaded into the map, they show the same image for all of them.

Let's say I have to load two annotations with this information:

Annotation 1 Name (title): Joshua Datetime (subtitle): 19/06, 11:00 Image: www.myurl.com/joshua.jpg

Annotation 2 Name (title): Mathew Datetime (subtitle): 10/06, 20:00 Image: www.myurl.com/mathew.jpg

Sometimes they are shown with title and subtitle correctly but the image loaded is the same for all of them (joshua's image or vice versa).

Am I missing something here is this method?

1

1 Answers

1
votes

The call to dequeueReusableAnnotationViewWithIdentifier: will at the first call return nil which will satisfy annotationView == nil and set up your annotation view. So all the following calls to dequeueReusableAnnotationViewWithIdentifier: will return the first created annotation view with the assigned avatar image.

So [userAvatar setImageWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"https://graph.facebook.com/%@/picture?type=small",[[(MapAnnotation *)annotation user] facebookID]]] placeholderImage:[UIImage imageNamed:@"user_placeholder"]]; is only called once.

You need to move annotation specific changes to the annotation view outside the "if nil" setup scope.

So you should instead set the userAvatar image each time the mapview ask for a annotationView. So something like this:

MKAnnotationView *annotationView = (MKAnnotationView *)[_mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
        if (annotationView == nil) {
            annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
            annotationView.enabled = YES;
            annotationView.canShowCallout = YES;
            annotationView.image = [UIImage imageNamed:@"map_pin"];

            UIImageView *userAvatar = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];
            userAvatar.layer.cornerRadius = 4.0;
            userAvatar.layer.masksToBounds = YES;
            userAvatar.layer.borderColor = [[UIColor blackColor] CGColor];
            userAvatar.layer.borderWidth = 1;

            annotationView.leftCalloutAccessoryView = userAvatar;

            UIButton *rightCallout = [UIButton buttonWithType:UIButtonTypeInfoLight];

            annotationView.rightCalloutAccessoryView = rightCallout;
        }
[((UIImageView *)annotationView.leftCalloutAccessoryView) setImageWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"https://graph.facebook.com/%@/picture?type=small",[[(MapAnnotation *)annotation user] facebookID]]] placeholderImage:[UIImage imageNamed:@"user_placeholder"]];

This will assign the correct image each time the map view asks for an annotation view.

Cheers Morten