6
votes

In my MKMap view I have customized the annotation pin with an image. But still some pins are static and not showing the given image.

I am using -(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id )annotation to set the pin image.

Adding my code and screen here:

-(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];
pinView.animatesDrop=YES;
pinView.canShowCallout=YES;
    pinView.pinColor= MKPinAnnotationColorGreen;

    pinView.enabled = YES;
    pinView.canShowCallout = YES;
    pinView.image=[UIImage imageNamed:@"bublerest.png"]; //here I am giving the image  





UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[rightButton setTitle:annotation.title forState:UIControlStateNormal];
[rightButton addTarget:self
                action:@selector(showDetails:)
      forControlEvents:UIControlEventTouchUpInside];

    pinView.rightCalloutAccessoryView = rightButton;

UIImageView *profileIconView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"rest_image2.png"]];
pinView.leftCalloutAccessoryView = profileIconView;


return pinView;
}

enter image description here

Any ideas?

4
Can you see your custom map icons at all for any pin or just some pins doesn't show them?Zhang

4 Answers

12
votes

If you want a different image on the MKAnnotationView than apples "Pin", you have to use a MKAnnotationView instead of a MKPinAnnotationView.

MKPinAnnotationView is not meant to be customized this way and will keep showing the Pin from time to time. The Class Reference shows that only pinColor and animatesDrop are supposed to be changed.

You will lose the PinAnnotationView's animation and shadow, though.

2
votes

Create a property in the MKAnnotation Protocol which will be used to set the pin e.g

@interface AddressAnnotation1 : NSObject<MKAnnotation> {
}
@property (nonatomic, retain) NSString *mPinColor;

In the .m file implementation file

- (NSString *)pincolor{
    return mPinColor;
}

- (void) setpincolor:(NSString*) String1{
    mPinColor = String1;
}

When you add the annotation, set the pin color also.

#pragma mark annotation delegate
- (MKAnnotationView *) mapView:(MKMapView *)mapView1 viewForAnnotation:(AddressAnnotation1 *) annotation
{
    UIImage *anImage = nil;

    MKAnnotationView *annView=(MKAnnotationView*)[mapView1 dequeueReusableAnnotationViewWithIdentifier:@"annotation"];
    if(annView==nil){
        annView=[[[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"annotation"] autorelease];
    }
    if([annotation.mPinColor isEqualToString:@"green"])
    {
        anImage=[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Google map pin 02.png" ofType:nil]];
    }
    else if([annotation.mPinColor isEqualToString:@"red"])
    {
        anImage=[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Google map pin 01.png" ofType:nil]];
    }
    else if([annotation.mPinColor isEqualToString:@"blue"])
    {
        anImage=[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Google map pin 02.png" ofType:nil]];
    }
    annView.image = anImage;
return annView;
}

If you don't want custom images for pins replace body of conditional statements with

annView.pinColor = MKPinAnnotationColorGreen;

or

annView.pinColor = MKPinAnnotationColorRed;

or

annView.pinColor = MKPinAnnotationColorPurple;

I have implemented this before. So have a go with it.

1
votes

Posting a sample snippet which I used in a recent project. Hope this helps.

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

Annotation *annotationInst = (Annotation*)annotation;

MKAnnotationView *pinView = nil;
if(annotation != mapView.userLocation)
{
    static NSString *defaultPinID = @"pinId";
    pinView = (MKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:defaultPinID];

    if ( pinView == nil ){
        pinView = [[[MKAnnotationView alloc]
                   initWithAnnotation:annotation reuseIdentifier:defaultPinID]autorelease];           
    }


    pinView.canShowCallout = YES;
    pinView.image = [UIImage imageNamed:LOCATION_BUBBLE];

    UIButton *rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
    pinView.rightCalloutAccessoryView = rightButton;
}    
return pinView;    
}
1
votes

Use this in viewForAnnotation

if ([annotation isKindOfClass:[MyAnnotation class]]) {
    // try to dequeue an existing pin view first
    static NSString* myAnnotationIdentifier = @"MyAnnotationIdentifier";

    // If an existing pin view was not available, create one
    MKPinAnnotationView* customPinView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:myAnnotationIdentifier];

    if ([(MyAnnotation *)annotation ann] == AnnotationTypeStart) {
        NSLog(@"In Start");
        customPinView.enabled = NO;
        customPinView.image = [UIImage imageNamed:@"begin.png"];
    }
}

where MyAnnotation is implemented as below

typedef enum AnnotationType {
    AnnotationTypeStart,
    AnnotationTypeEnd,
    AnnotationTypeWayPoint,
} AnnotationType;

@interface MyAnnotation : NSObject <MKAnnotation> {
    CLLocationCoordinate2D coordinate;
    NSString *title;
    NSString *subtitle;
    AnnotationType ann;
}