iosobjective-cmapkitmkpinannotationview

MapKit custom pin annotation


I have the following files:

annotation.h:

#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>

@interface annotation : NSObject <MKAnnotation>

@property(nonatomic, assign) CLLocationCoordinate2D coordinate;
@property(nonatomic, copy) NSString *title;
@property(nonatomic, copy) NSString *subtitle;


@end

annotation.m:

#import "annotation.h"

@implementation annotation

@synthesize coordinate, title, subtitle;

@end

And in the main code, which takes in an NSURL found elsewhere:

[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
[spinner stopAnimating];

// json parsing
results = [NSJSONSerialization JSONObjectWithData:data options:nil error:nil];

NSMutableArray * locations = [[NSMutableArray alloc] init];
CLLocationCoordinate2D location;
annotation * myAnn;

NSArray *pins = mapView.annotations;

if ([pins count])
{
    [mapView removeAnnotations:pins];
}

/* loop through the array, each key in the array has a JSON String with format:
 * title <- string
 * strap <- string
 * id <- int
 * date <- date
 * lat <- floating point double
 * long <- floating point double
 * link <- string

 */
int i;

for (i = 0; i < [results count]; i++) {
    //NSLog(@"Result: %i = %@", i, results[i]);
    //NSLog(@"%@",[[results objectAtIndex:i] objectForKey:@"long"]);

    myAnn = [[annotation alloc] init];
    location.latitude = (double)[[[results objectAtIndex:i] objectForKey:@"lat"] doubleValue];
    location.longitude = (double)[[[results objectAtIndex:i] objectForKey:@"long"] doubleValue];
    myAnn.coordinate = location;
    myAnn.title = [[results objectAtIndex:i] objectForKey:@"title"];
    myAnn.subtitle = [[results objectAtIndex:i] objectForKey:@"strap"];

    [locations addObject:myAnn];

    //NSLog(@"%i", [[results objectAtIndex:i] objectForKey:@"lat"]);
}

[self.mapView addAnnotations:locations];

Previous things I have looked at for this say that I need to use MKAnnotationView as opposed to MKPinAnnotationView but as you can see I do not use either, is it possible for me to use custom images for the pins that are dropped on the screen.


Solution

  • You (a) make sure to define your view controller to be the delegate for your MKMapView; and (b) implement viewForAnnotation, e.g.:

    - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
        if ([annotation isKindOfClass:[MKUserLocation class]]) {
            return nil;
        }
    
        if ([annotation isKindOfClass:[CustomAnnotation class]]) {
            static NSString * const identifier = @"MyCustomAnnotation";
                        
            MKAnnotationView* annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
            
            if (annotationView) {
                annotationView.annotation = annotation;
            } else {
                annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation
                                                              reuseIdentifier:identifier];
            }
    
            // set your annotationView properties
            
            annotationView.image = [UIImage imageNamed:@"Your image here"];
            annotationView.canShowCallout = YES;
    
            // if you add QuartzCore to your project, you can set shadows for your image, too
            //
            // [annotationView.layer setShadowColor:[UIColor blackColor].CGColor];
            // [annotationView.layer setShadowOpacity:1.0f];
            // [annotationView.layer setShadowRadius:5.0f];
            // [annotationView.layer setShadowOffset:CGSizeMake(0, 0)];
            // [annotationView setBackgroundColor:[UIColor whiteColor]];
            
            return annotationView;
        }
    
        return nil;
    }
    

    By the way, in my example above, I changed the name of your annotation class to CustomAnnotation. annotation is a horrible name for a class because (a) it doesn't follow class naming conventions of upper case first letter; and (b) it's identical to the variable name, annotation, that many MKMapViewDelegate methods will use by default.

    References