I figured out how achieve flicker free annotation "updates" using the below code. In a nut shell, you add your new pin FIRST, then delete the old one AFTER. I haven't streamlined my code yet but you'll get the idea.
-(void)replacePin:(NSString *)title SubTitle:(NSString *)subTitle Location:(CLLocationCoordinate2D)location PinType:(MapAnnotationType)pinType Loading:(BOOL)loading Progress:(float)progress
{
//Find and "decommission" the old pin... (basically flags it for deletion later)
for (MyMapAnnotation *annotation in map.annotations)
{
if (![annotation isKindOfClass:[MKUserLocation class]])
{
if ([annotation.title isEqualToString:title])
annotation.decommissioned = YES;
}
}
//add the new pin...
MyMapAnnotation *stationPin = nil;
stationPin = [[MyMapAnnotation alloc] initWithCoordinate:Location
annotationType:pinType
title:title
subtitle:subTitle
loading:loading
decommissioned:NO
progress:progress];
[map addAnnotation:stationPin];
[stationPin release];
}
Then AFTER, I make the call to search for and remove any decommissioned pins:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
MKAnnotationView* annotationView = nil;
if (![annotation isKindOfClass:[MKUserLocation class]])
{
MyMapAnnotation* annotation = (MyMapAnnotation*)annotation;
//your own details...
//delete any decommissioned pins...
[self performSelectorOnMainThread:@selector(deletePin:) withObject:annotation.title waitUntilDone:NO];
}
return annotationView;
}
And finally, in the background get rid of the old pin:
-(void)deletePin:(NSString *)stationCode
{
for (MyMapAnnotation *annotation in map.annotations)
{
if (![annotation isKindOfClass:[MKUserLocation class]])
{
if ([annotation.title isEqualToString:stationCode])
{
if (annotation.decommissioned)
[map removeAnnotation:annotation];
}
}
}
}