I want to display different colour pins in a UIMapView based on the relative time they represent
but it seems the mapView:viewForAnnotation: method only does it\'s thing
There is no guarantee that the viewForAnnotation
will be called immediately after addAnnotation
or that it will be called only once.
The annotation could be added in a region that isn't currently visible or the user might pan or zoom the map which causes the annotation to come back into view. The map view will simply call it whenever or as often as it needs to.
This is by-design and simply how the delegate method approach works.
For this reason, your implementation of the delegate method should generally only use the annotation
parameter passed to the method as the basis for all the logic inside the method. It should not rely on any external variables or make broad assumptions about when it will be called.
For other answers that may explain this in more detail, see:
For your question specifically, I suggest the following:
Right now you're adding annotations of type MKPointAnnotation
which don't contain the "age" information that the viewForAnnotation
method needs (I'm assuming this is what it needs).
Instead of using MKPointAnnotation
, make your Finding
class (or whatever the type is of the self.finding
object) implement the MKAnnotation
protocol itself. You should be able to find several examples of custom annotation classes on SO.
Then, instead of keeping an annotationFlag
variable and creating MKPointAnnotation
objects, add the Finding
objects themselves (which contain their "age") directly to the map when calling addAnnotation
.
In viewForAnnotation
, set the pinColor
after the if-else that creates/dequeues the view and just before the return
. Be sure to set the pinColor
based on the age property of the annotation
object passed into the method (which will be a Finding
type object). For example:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id)annotation
{
if([annotation isKindOfClass:[MKUserLocation class]])
return nil;
static NSString *identifier = @"myAnnotation";
MKPinAnnotationView * annotationView = (MKPinAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
if (!annotationView)
{
annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
annotationView.animatesDrop = YES;
annotationView.canShowCallout = NO;
annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeSystem];
}else {
annotationView.annotation = annotation;
}
//update the pinColor in the view whether it's a new OR dequeued view...
if ([annotation isKindOfClass:[Finding class]])
{
Finding *f = (Finding *)annotation;
if ([f.age isEqualToString:@"2"]) {
annotationView.pinColor = MKPinAnnotationColorGreen;
}
else if ([f.age isEqualToString:@"1"]) {
annotationView.pinColor = MKPinAnnotationColorPurple;
}
else {
annotationView.pinColor = MKPinAnnotationColorRed;
}
}
return annotationView;
}