I use plist file to store annotation data that have Name, Address, Coordinates and Icon (pin image name) strings in dictionary. I need to show my annotations on map with pin image depending on Icon string in plist. I loop my annotation dictionaries but it show on map pin image from first dict on all my pins.
My code:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[MKUserLocation class]])
return nil;
static NSString* AnnotationIdentifier = @"AnnotationIdentifier";
MKPinAnnotationView* pinView = [[MKPinAnnotationView alloc]
initWithAnnotation:annotation reuseIdentifier:AnnotationIdentifier];
NSString *path = [[NSBundle mainBundle] pathForResource:@"data" ofType:@"plist"];
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];
for(path in dict){
NSString *theCategory;
theCategory = [NSString stringWithFormat:@"%@", path];
NSLog(@"%@", path);
NSArray *anns = [dict objectForKey:theCategory];
pinView.image = [UIImage imageNamed:[[anns objectAtIndex:0] objectForKey:@"Icon"]];
}
pinView.canShowCallout=YES;
return pinView;
}
My plist file construction:

What it show to me:

The
viewForAnnotationdelegate method will get called for each annotation added.The for-loop you have inside that method will run the same way for each annotation. All the for-loop ends up doing (every time for each annotation) is setting
pinView.imageto the last item read by the for-loop. This happens to be the first item in the first dictionary in the plist.You need to instead set
pinView.imageto theIconof the item that is for the current annotation thatviewForAnnotationis being called for (ie. theannotationparameter that is passed). So you could keep the for-loop and check if the item matchesannotationand only then setpinView.image(and thenbreakout of the for-loop).But it’s not a good idea to constantly be re-reading and looping through a plist in that delegate method. It’s better to make
Icona property of your annotation class, set the property when creating the annotation (you are probably looping through the plist to create the annotations in the first place), and then just use that property directly from the annotation object itself in theviewForAnnotationdelegate method.Assuming you have some custom annotation class, add Icon as a property:
Then in the place where you loop through the plist to create the annotations, set the
iconproperty just like you are setting thetitleproperty:Finally, in
viewForAnnotation, you can read theiconproperty directly from theannotation. But first, you should check thatannotationis of your custom class type (so the user location blue dot is not affected and to be reasonably sureannotationwill have the property you’re about to access):By the way, in your plist file,
Test3has noIconsetting.