Reputation: 1478
As far as I know, there isn't a way to move an annotation without removing & re-adding it to the MapView (Maybe I'm wrong).
Is there a way to prevent the MapView from being re-drawn between removing & re-adding the annotation? Right now the re-draw after removing the annotation causes a frame without the annotation, so it appears to flicker.
I need a solution that works in iOS 3.1 updates.
Thanks
Upvotes: 3
Views: 5970
Reputation: 12946
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];
}
}
}
}
Upvotes: 6
Reputation: 2289
For 3.1 you'll have to hack. I'd see two possibilities, either trying to force change the coordinates of the current annotation by lurking around in the header files and accessing the memory directly, or fiddling with UIWindow and graphic contexts to try to avoid the drawing done in next runloop cycle to actually reach the screen.
Edit: a third alternative, which might be the easiest, is to do your own lightweight annotation implementation outside of MapKit..
Upvotes: 1