MKMapview annotation dynamic pin image changes after zooming

纵然是瞬间 提交于 2019-11-30 21:15:10

One issue is that the viewForAnnotation is determining the correct image to show based upon a class instance variable. Generally the identifier for the annotation's image would be a property of the custom annotation itself, not some external instance variable.

On top of that, it appeared that the annotation was being added to the map before all of the annotation's properties were being set. One should defer the addAnnotation until all of the annotation's properties are set.

Alternatively, you can add the annotations to a NSMutableArray, tweak them as you see fit, and only add the annotations at the very end using the addAnnotations (note the s), passing it the array.

The main problem is that the code in viewForAnnotation is relying on the outside variable _mapView.tag to determine the annotation view.

It is unsafe to assume when and how frequently the viewForAnnotation delegate method will be called by the map.

If an annotation's view depends on certain values, it is generally best to embed those values directly in the annotation object itself. This way, in the viewForAnnotation delegate method, you can reference those annotation-specific values through the annotation parameter that is passed to the method. Those annotation-specific values should be set when creating the annotation (before calling addAnnotation).

For some more details and examples, see:

A separate issue is the code is setting annotationView to nil after calling dequeueReusableAnnotationViewWithIdentifier which defeats the dequeue.


At least in viewForAnnotation, the corrected code where it handles the Annotation class might look like this (not the whole method -- just the part inside the second if):

static NSString *identifier = @"ann";

CustomAnnotationView* annotationView = (CustomAnnotationView*)[mapView 
    dequeueReusableAnnotationViewWithIdentifier:identifier];

//annotationView = nil;  // <-- remove this line

if (annotationView == nil) 
{
    annotationView = [[CustomAnnotationView alloc] 
                         initWithAnnotation:annotation 
                         reuseIdentifier:identifier];
    annotationView.enabled = YES;
    annotationView.canShowCallout = YES;
}
else
{
    annotationView.annotation = annotation;
}

//MOVE the setting of the image to AFTER the dequeue/create 
//because the image property of the annotation view 
//is based on the annotation and we can update image in one place
//after both the dequeue and create are done...

//Get the image name from the annotation ITSELF 
//from a custom property (that you add/set)
Annotation *myCustomAnn = (Annotation *)annotation;

NSString *imgName = myCustomAnn.imageName;  
//imageName is the custom property you added/set

UIImage *img = [UIImage imageNamed:
                   [NSString stringWithFormat:@"%@.png",imgName]];

annotationView.image = img;

return annotationView;

SOLVED by Rob

The problem was, that I could not retrive the annotation properties which I set at my VC. The reason was that I used the [_mapView addAnnotation:ann]; command, before I set all the annotation's properties. That said, by moving this line to the end part of the annotation initial properties setup, solved the problem.

Thank you all and big thanks to Rob! I'm up to my next challenge.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!