I want my annotations in two colors. For that I have used following code,
- (MKAnnotationView *)mapView:(MKMapView *)sender viewForAnnotation:(id <MKAnnotation>)annotation {
static NSString *identifier = @"MyLocation";
if ([annotation isKindOfClass:[PlaceMark class]]) {
MKPinAnnotationView *annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
annotationView.enabled = YES;
annotationView.canShowCallout = YES;
@try {
if (annotationView == nil) {
annotationView = [[MKPinAnnotationView alloc]
initWithAnnotation:annotation
reuseIdentifier:identifier];
} else {
annotationView.annotation = annotation;
if([[nsCenterOrOffice objectAtIndex:z] isEqualToString:@"C"])
{
annotationView.pinColor = MKPinAnnotationColorRed;
}
else
{
annotationView.pinColor = MKPinAnnotationColorGreen;
}
}
}
@catch (NSException *exception) {
NSLog(@"nsCenterOrOffice exception = %@",exception);
}
return annotationView;
}
return nil;
}
But still I am not able to set desired color for desired annotation. Sometimes particular annotation pin color is red and sometimes it's green. I am not getting why this is happening. Can anybody help me ? Thanks...
I rework on my code..this is my updated code
MapAnnotation.h
#import <MapKit/MapKit.h>
#import <Foundation/Foundation.h>
@interface MapAnnotation : MKPointAnnotation
{
NSString *title;
NSString *subtitle;
int dealLnk;
float latitude;
float longitude;
CLLocationCoordinate2D coordinate;
}
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *subtitle;
@property (nonatomic, assign) int dealLnk;
@property (nonatomic, assign) float latitude;
@property (nonatomic, assign) float longitude;
@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
- (id)initWithTitle:(NSString *)ttl subTitle:(NSString *)subttl dealLink:(int)dealLnk latitude:(float)latitude longitude:(float)longitude andCoordinate:(CLLocationCoordinate2D)c2d;
@end
MapAnnotation.m
#import "MapAnnotation.h"
@implementation MapAnnotation
@synthesize title,subtitle,dealLnk,coordinate,latitude,longitude;
- (id)initWithTitle:(NSString *)ttl subTitle:(NSString *)subttl dealLink:(int)z latitude:(float)latitude1 longitude:(float)longitude1 andCoordinate:(CLLocationCoordinate2D)c2d {
title = ttl;
subtitle = subttl;
dealLnk =z;
coordinate = c2d;
longitude = longitude1;
latitude = latitude1;
return self;
}
@end
And this is my implementation file
-(void)startAddingAnnotation
{
@try {
CLLocationCoordinate2D annotationCoord;
z=0;
for (int i=0; i < [nslatitude count] ; i++,z++)
{
MapAnnotation *dealAnnotation = [[MapAnnotation alloc] init];
dealAnnotation.dealLnk = z;
annotationCoord.latitude = (CGFloat) [[nslatitude objectAtIndex:i] floatValue];
annotationCoord.longitude = (CGFloat)[[nslongitude objectAtIndex:i] floatValue];
dealAnnotation.coordinate = annotationCoord;
dealAnnotation.title = [nsCenterName objectAtIndex:i];
dealAnnotation.subtitle = [nsCenterAddress objectAtIndex:i];
NSLog(@"latitude = %f",dealAnnotation.latitude);
NSLog(@"longitude = %f",dealAnnotation.longitude);
NSLog(@"dealAnnotation.dealLnk = %d",dealAnnotation.dealLnk);
NSLog(@"dz = %d",z);
[mapView addAnnotation:dealAnnotation];
}
}
@catch (NSException *exception) {
NSLog(@"Exception = %@",exception);
}
cord.longitude = -112.05186;
cord.latitude = 33.46577;
MKCoordinateRegion region;
region.center = cord;
MKCoordinateSpan span = {.latitudeDelta = 1.0, .longitudeDelta = 1.0};
region.span = span;
[mapView setRegion:region];
}
#pragma mark - MapView_Delegate
- (MKAnnotationView *)mapView:(MKMapView *)sender viewForAnnotation:(id <MKAnnotation>)annotation {
MapAnnotation *annotation1 = (MapAnnotation *)annotation;
z = annotation1.dealLnk;
NSLog(@"annotation1.longitude = %f",annotation1.latitude);
NSLog(@"annotation1.longitude = %f",annotation1.longitude);
if(z<[nslatitude count])
{
MKAnnotationView *pinView = nil;
static NSString *defaultPinID = @"pin1";
pinView = (MKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:defaultPinID];
if ( pinView == nil )
pinView = [[MKAnnotationView alloc]
initWithAnnotation:annotation1 reuseIdentifier:defaultPinID];
pinView.canShowCallout = YES;
@try {
if([[nsCenterOrOffice objectAtIndex:z] isEqualToString:@"C"])
{
pinView.image = [UIImage imageNamed:@"flag1.png"];
}
else
{
pinView.image = [UIImage imageNamed:@"flag2.png"];
}
pinView.annotation = annotation1;
pinView.tag = [[nsCenterName objectAtIndex:z] intValue];
}
@catch (NSException *exception) {
NSLog(@"nsCenterOrOffice exception = %@",exception);
}
UIButton *rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[rightButton setTitle:annotation.title forState:UIControlStateNormal];
[pinView setRightCalloutAccessoryView:rightButton];
return pinView;
}
else
{
return nil;
}
}
Now the problem is, all the annotations are pointing some different location. I am not getting why this is happening? Is der anything wrong in my code?
Your
viewForAnnotation
is relying upon some external variables,nsCenterOrOffice
andz
. We certainly can't help you until you show us how you're setting those variables.Regardless, this is not a prudent practice. Your
viewForAnnotation
generally should rely solely upon properties of theannotation
, not external variables.The condition that determines the pin color is based on data outside of this delegate method and there is no guarantee that it will be in sync with when this delegate method is called for a particular annotation.
In this
if
condition:the
z
variable is apparently some instance variable declared and set (probably right before adding an annotation) outside this delegate method.Again, there is no guarantee that the
viewForAnnotation
delegate method will be called immediately after an annotation is added. There is also no guarantee that the delegate method will be called only once for each annotation. So it's possible that thez
value does not correspond to the currentannotation
that the delegate method is being called for.It is very possible for the delegate method to be called well after
addAnnotation
is called, that it will be called in a different order than the annotations were added, and that it will be called multiple times for each annotation (eg. if user pans or zooms the map and annotations come back into view).To fix this, add the "is center or office" property to the
Placemark
class itself and set that property when creating the annotation and before callingaddAnnotation
. Then, in theviewForAnnotation
method, you can cast theannotation
parameter as aPlacemark
and access the property to implement the condition. For example:A separate, unrelated issue is that the annotation view creation logic is not quite right.
The code calls
initWithAnnotation
twice and in actuality the secondinitWithAnnotation
never gets called since the first call will always succeed.What you probably wanted was to first call
dequeueReusableAnnotationViewWithIdentifier:
and then, if that returnsnil
, callinitWithAnnotation
.When restructuring the code in
viewForAnnotation
, be sure to put the code that sets thepinColor
outside the dequeue/init of the annotation view (eg. right before thereturn annotationView;
) to properly handle reused views.