Map view annotations with different pin colors
Asked Answered
P

2

5

I have an array with over 200 objects and I am trying to perform a loop through each of them.

Each object will have a yes/no field and I want to display a different coloured marker dependent on that yes / no value.

From what I can see is happening my loop is going through each object first and then all the annotation is added at the end for each object .

Since I perform a check within my loop through the array on the yes no value when all the annotation is added to my map, it will use the yes/no value from the last object in the array when it goes to plot for all.

How can I have it so that the marker will be different dependent on the yes/no value for each individual element?

My code is

for (i = 0; i < [appDelegate.itemArray count]; i++) {
        item_details *tempObj = [appDelegate.itemArray objectAtIndex:i];
        location.latitude = [tempObj.lat floatValue];
        location.longitude = [tempObj.lon floatValue];
        current_yesno = tempObj.yesno;
        MapViewAnnotation *newAnnotation = [[MapViewAnnotation alloc]initWithTitle:tempObj.name andCoordinate:location];
        [self.mapView addAnnotation:newAnnotation];
        [newAnnotation release];            
            } 

with my annotation code as follows

- (MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>) annotation{

    MKPinAnnotationView *annView=[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"currentloc"];

if(current_yesno == YES){
    annView.pinColor = MKPinAnnotationColorGreen;
}
else
{
    annView.pinColor = MKPinAnnotationColorRed;
}
    annView.animatesDrop=NO;
    annView.canShowCallout = YES;
    annView.calloutOffset = CGPointMake(-5, 5);
    return annView;

}

and current_yesno is declared in my .h file.

Pickaxe answered 5/6, 2012 at 13:21 Comment(0)
I
8

The viewForAnnotation delegate method isn't necessarily called immediately after you do addAnnotation and it can also be called at other times by the map view when it needs to get the view for an annotation (while your code is doing something completely different).

So you can't depend on the value of an ivar being in sync with some code outside that delegate method.

Instead, add the yesno property to your custom MapViewAnnotation class, set it when creating the annotation and then access its value in viewForAnnotation through the annotation parameter (ie. the map view is giving you a reference to the exact annotation object it wants the view for).

Example:

MapViewAnnotation *newAnnotation = [[MapViewAnnotation alloc] init...
newAnnotation.yesno = tempObj.yesno;  // <-- set property in annotation
[self.mapView addAnnotation:newAnnotation];

Then in viewForAnnotation:

- (MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>) annotation
{
    if (![annotation isKindOfClass:[MapViewAnnotation class]])
    {
        // Return nil (default view) if annotation is 
        // anything but your custom class.
        return nil;
    }

    static NSString *reuseId = @"currentloc";

    MKPinAnnotationView *annView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:reuseId];
    if (annView == nil)
    {
        annView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:reuseId];        
        annView.animatesDrop = NO;
        annView.canShowCallout = YES;
        annView.calloutOffset = CGPointMake(-5, 5);
    }
    else
    {
        annView.annotation = annotation;
    }

    MapViewAnnotation *mvAnn = (MapViewAnnotation *)annotation;
    if (mvAnn.yesno)
    {
        annView.pinColor = MKPinAnnotationColorGreen;
    }
    else
    {
        annView.pinColor = MKPinAnnotationColorRed;
    }

    return annView;
}
Instructor answered 5/6, 2012 at 15:31 Comment(3)
Thanks for the reply. How do i add the property yesno toMapViewAnnotation ?Pickaxe
In MapViewAnnotation.h, put @property(nonatomic, assign) BOOL yesno; and in MapViewAnnotation.m put @synthesize yesno;Instructor
Thanks Anna, stil a relevant answer.Epiglottis
L
0
MKPinAnnotationView *pin = (MKPinAnnotationView *) [self.mapView dequeueReusableAnnotationViewWithIdentifier: @"id"];
if (pin == nil)
{
    pin = [[MKPinAnnotationView alloc] initWithAnnotation: annotation reuseIdentifier: @"id"] ;
}
else
{
    pin.annotation = annotation;
}

pin.pinTintColor=[UIColor blueColor];
pin.canShowCallout = true;
Loudermilk answered 2/10, 2015 at 6:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.