Custom Map Pins for MapKit

In my last MapKit post, I told you how to create custom polygon overlays for your maps.  Now we are going to add to that project and create custom Parking lot icons to place over our polygon shapes so people know what they are. If you want to follow along, make sure you download the project file from that tutorial first: Download the Polygon Map Overlay sample project.

The first thing we’ll do is create a new class that conforms to the MKAnnotation protocol.  To do this, create a new NSObject based class, “MyAnnotationClass”.  In the header (.h) file, the only property that is required to conform with the MKAnnotation protocol is a “coordinate” property but I’m also going to add “name” and “description” property for use later. You’ll need to:

  1. Import MapKit/MapKit.h
  2. Add the MKAnnotation protocol
  3. Add the coordinate property
  4. Create an init method


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

@interface MyAnnotationClass : NSObject {
NSString *_name;
NSString *_description;
CLLocationCoordinate2D _coordinate;

}
@property (nonatomic, retain) NSString *name;
@property (nonatomic, retain) NSString *description;
@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;

-(id) initWithCoordinate:(CLLocationCoordinate2D) coordinate;

@end

Our implementation (.m) file is very simple too:

#import "MyAnnotationClass.h"

@implementation MyAnnotationClass

@synthesize name = _name;
@synthesize description = _description;
@synthesize coordinate = _coordinate;

-(id) initWithCoordinate:(CLLocationCoordinate2D) coordinate{
self=[super init];
if(self){
_coordinate=coordinate;
}
return self;
}

-(void) dealloc{
self.name = nil;
self.description = nil;
[super dealloc];
}
@end

 

That’s it for our class. Pretty simple. Now it’s time to add some annotations to our map. Head over to your header (.h) file for your view controller where your map is and I’m going to add an array to store my annotations because then I can add all the annotations at once rather then call “addAnnotation” multiple times. Also add an import statement for “MyAnnotationClass.h”


#import <uikit/UIKit.h>
#import
<mapKit/MapKit.h> #import "MyAnnotationClass.h"

@interface PolygonOverlaySampleViewController : UIViewController {
MKMapView *_myMapView;
NSArray *_myAnnotations;
}

@property (nonatomic, retain) NSArray *myAnnotations;
@property (nonatomic, retain) IBOutlet MKMapView *myMapView;

@end

Now switch to your implementation (.m) file for your view controller. It’s quite simple to add these annotations to your map.

  1. Initialize your annotations
  2. Add them to the array
  3. release the annotations (you just added them to the array so they are retained in there)
  4. Add the array of annotations to the map


-(void) viewDidLoad{
...
//Initialize annotation
MyAnnotationClass *commuterLotAnnotation=[[MyAnnotationClass alloc] initWithCoordinate:CLLocationCoordinate2DMake( 39.047752, -76.850388)];
MyAnnotationClass *overflowLotAnnotation=[[MyAnnotationClass alloc] initWithCoordinate:CLLocationCoordinate2DMake( 39.047958, -76.852520)];

//Add them to array
self.myAnnotations=[NSArray arrayWithObjects:commuterLotAnnotation, overflowLotAnnotation, nil];

//Release the annotations now that they’ve been added to the array
[commuterLotAnnotation release];
[overflowLotAnnotation release];

//add array of annotations to map
[_myMapView addAnnotations:_myAnnotations];
}

Now build and run your app. You’ll notice that you have to red pins on the parking lot. Great but that’s not what you wanted, you wanted a custom icon right? To do that, we need to implement a MapView Delegate method: -(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation This takes an annotation for an argument and returns a MKAnnotationView. One thing to note is that method is very similar to a TableViewController in that it will try to reuse MKAnnotationView that is not being used or shown rather than create a new one. If one isn’t available, you create one and give it an identifier so you can reuse it later.

MKAnnotationView has a few interesting properties but the one we are interested in is image. So we’ll set the image for annotation view to be our parking lot icon.


-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id)annotation{
static NSString *parkingAnnotationIdentifier=@"ParkingAnnotationIdentifier";

if([annotation isKindOfClass:[MyAnnotationClass class]]){
//Try to get an unused annotation, similar to uitableviewcells
MKAnnotationView *annotationView=[mapView dequeueReusableAnnotationViewWithIdentifier:parkingAnnotationIdentifier];
//If one isn’t available, create a new one
if(!annotationView){
annotationView=[[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:parkingAnnotationIdentifier];
//Here’s where the magic happens
annotationView.image=[UIImage imageNamed:@”parkingIcon.png”];
}
return annotationView;
}
return nil;
}

Now build and run your app:
IOS Simulator - parking icon

You should see the parking icons!

Download the Polygon Map Overlay with Custom Map Pins sample project.

6 Responses to “Custom Map Pins for MapKit”

  1. Henry
    April 25, 2011 at 2:59 pm #

    Hmm… I cant get it to work?
    Not even the sample project works. I get a warning in the MKAnnotationView method.

    I’m trying to set an image on top of a building, I dont know this will work.

    • Shawn Grimes
      May 12, 2011 at 2:48 pm #

      Hi Henry,
      I just downloaded the file from this post and it worked for me.

      What is the error you are getting? Are you using Xcode 3 or 4?

  2. monica
    November 16, 2012 at 6:25 am #

    I am not able to download the project.pls help me out.

  3. Shawn
    December 18, 2012 at 3:28 am #

    Thanks, works great. Any solution to set the size of the annotation and how can we show 2,3 different ones ?

Trackbacks/Pingbacks

  1. New Core Location and Map Kit workshop | Shawn's Bits - June 30, 2011

    […] written a few tutorials on this site that discussed customizing MapKit. These tutorials were sometimes difficult to explain in text and the comments showed it. I’ll […]

Leave a Reply