Reputation: 16793
As you can see below, I have simulated my problem in a basic way. I have a timer that calls a method periodically. In that method, I have created a switch-case condition to simulate my idea.
Once pin is added on the map, then reading (pin keeps dropping) them again.
I want to add my pin and then just only change the title that represents a weather value.
- (IBAction)playBtn:(id)sender {
timer = [NSTimer scheduledTimerWithTimeInterval:(4.0) target:self selector:@selector(control) userInfo:nil repeats:YES];
}
-(void)control{
NSMutableArray *annotationArray = [[[NSMutableArray alloc] init] autorelease];
switch (value%2) {
case 0:
{
// Create some annotations
Annotation *annotation = nil;
annotation = [[Annotation alloc] init];
annotation.coordinate = CLLocationCoordinate2DMake(29.7161,-95.3906);
annotation.color = RGB(13, 0, 182);
annotation.title = @"17";
[annotationArray addObject:annotation];
[annotation release];
annotation = [[Annotation alloc] init];
annotation.coordinate = CLLocationCoordinate2DMake(30.168456,-95.504480);
annotation.color = RGB(0, 182, 146);
annotation.title = @"16";
[annotationArray addObject:annotation];
[annotation release];
// Center map
//self.mapView.visibleMapRect = [self makeMapRectWithAnnotations:annotationArray];
// Add to map
//[self.mapView addAnnotations:annotationArray];
}
break;
case 1:
{
// Create some annotations
Annotation *annotation = nil;
annotation = [[Annotation alloc] init];
annotation.coordinate = CLLocationCoordinate2DMake(29.7161,-95.3906);
annotation.color = RGB(13, 0, 182);
annotation.title = @"27";
[annotationArray addObject:annotation];
[annotation release];
annotation = [[Annotation alloc] init];
annotation.coordinate = CLLocationCoordinate2DMake(30.168456,-95.504480);
annotation.color = RGB(0, 182, 146);
annotation.title = @"25";
[annotationArray addObject:annotation];
[annotation release];
}
break;
}
[self.mapView addAnnotations:annotationArray];
[mapView setNeedsDisplay];
value++;
Upvotes: 3
Views: 5069
Reputation:
If you want to update the properties of an annotation that has already been added to the map, adding it again with the new properties (without first removing the old one) just creates and adds another annotation at the same location (with the new properties).
As you saw, calling removeAnnotation
and then addAnnotation
results in flicker and another drop animation.
Instead, you have to get a reference to the existing annotation and then update its properties.
If it's just one annotation, you could keep a class-level ivar reference to it and update the properties with that reference when the values change.
If you need to update different annotations at different times, a simple way is to search the map view's annotations
array for the annotation you want to update.
This requires that you have a property in your annotation class that will be unique for each annotation and (ideally) remain constant for each annotation. In other words: if you're going to be updating the annotation's title
, don't use the title
as the "unique" annotation identifier.
Instead, add another property (eg. an int or string) that you assign to each annotation when creating it and which won't change so you can find the annotation later using that value.
For example, assume you add an int property called annotationId
to your annotation class and you want to update the annotation with id# 42:
BOOL annFound = NO;
//loop through the map view's annotations array to find annotation id# 42...
for (id<MKAnnotation> ann in mapView.annotations)
{
if ([ann isKindOfClass:[MyAnnotationClass class]])
{
MyAnnotationClass *myAnn = (MyAnnotationClass *)ann;
if (myAnn.annotationId == 42)
{
annFound = YES;
myAnn.title = @"some new title";
break;
}
}
}
if (!annFound)
{
//annotation id# 42 is not yet on the map.
//create it and add to map...
}
Upvotes: 7
Reputation: 111
I think you need to remove the old annotations, since the annotaions array is read only NSArray *oldAnnotaions = [map annotaions]; [mapView removeAnnotations:oldAnnotations];
Upvotes: 0