3

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++;
casillas
  • 16,351
  • 19
  • 115
  • 215

2 Answers2

7

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... 
}
  • Hello Anna, first of all, I would like to thank you a lot. pin title now is able to change without flickering. Now, I would like to change my pin color as well. However, even though I am using annotaionId to change the pin color but it is not changing.if(a.annotationId==42){a.title=@"15"; a.color=RGB(0,0,0);} .. pin color does not change!! thanks a lot in again. – casillas Sep 14 '12 at 04:37
  • one more question, the code that you wrote above should be inside (MKAnnotationView *)mapView:(MKMapView *)mV viewForAnnotation:(id )annotation ? – casillas Sep 14 '12 at 05:53
  • 1
    No, this code should not be inside viewForAnnotation. It should be wherever the annotation properties change. One thing I forgot to mention is that if any of the annotation properties affect the annotation _view_ then you need to do something more to force it to update. The title works because MKAnnotationView already monitors changes to that property for the callout. –  Sep 14 '12 at 10:49
  • 1
    See these questions for examples of how to force the annotation view to change after updating the annotation properties: http://stackoverflow.com/questions/12264854/change-mkannotationview-programmatically, http://stackoverflow.com/questions/6808792/change-uiimage-from-mkannotation-in-the-mkmapview, http://stackoverflow.com/questions/10439335/change-annotation-image-after-its-created. –  Sep 14 '12 at 10:51
  • Thanks a lot Anna, for giving such a deep information.Now I can capable of changing color of pin and title. – casillas Sep 14 '12 at 15:08
  • Hello Anna, sorry for bothering u again..could u please take a look at my question that I have just posted http://stackoverflow.com/questions/12594112/remove-annotation-from-mapview-like-google-map-app – casillas Sep 26 '12 at 03:25
  • i would recommend using an NSSet and overriding isEqual and hash on your annotation classes – Heavy_Bullets Sep 18 '13 at 22:10
0

I think you need to remove the old annotations, since the annotaions array is read only NSArray *oldAnnotaions = [map annotaions]; [mapView removeAnnotations:oldAnnotations];

RexMac66
  • 111
  • 1
  • 9
  • first of all, thanks for the quickly reply. However, I removed old annotations already. But while adding them again, it still keeps dropping pin on the map.I don't want pin to be dropped, I just want to pin to stay there but title and subtitle would change. – casillas Sep 13 '12 at 23:02