I have a mapview that displays locations of cash points. Annotations are dropped and the callout can be clicked on to go to a page with more detail about that location. Ther
It's not a problem related to the map reloading tiles.
The issue is that the code in the viewForAnnotation
delegate is using the ann
object with the incorrect assumption that the class-instance-level ann
object will be in sync with whenever the delegate method is called.
The viewForAnnotation
delegate is not necessarily called in the order that you add annotations and can be called multiple times for the same annotation if the map needs to re-display an annotation when it comes back into view.
When the delegate method gets called again for a previously added annotation, ann
and annotation
no longer point to the same object. ann
is now probably pointing to the last added annotation and so all the annotations change to its color.
In that delegate method, you must use the annotation
parameter which is a reference to the annotation that the map view wants the view for in the current call (which may be completely unrelated to your outside loop).
So this line:
MKPinAnnotationView *mypin = [[MKPinAnnotationView alloc]
initWithAnnotation:ann reuseIdentifier:@"current"];
should be:
MKPinAnnotationView *mypin = [[MKPinAnnotationView alloc]
initWithAnnotation:annotation reuseIdentifier:@"current"];
^^^^^^^^^^
and when checking the annotation's properties, use the annotation
parameter (and cast it to your custom class to get at the custom properties):
PinDrop *ann = (PinDrop *)annotation;
//Note that this local "ann" is NOT the same as the class-level "ann".
//May want to use a different name to avoid confusion.
//The compiler may also warn you about this.
if (ann.price == 1)
...
A separate, unrelated, but highly recommended suggestion is to implement annotation view re-use by using dequeueReusableAnnotationViewWithIdentifier
. This will improve performance when you have lots of annotations.