A basic MapView and annotation tutorial

Map viewI suppose it was inevitable that I’d end up needing to use the Mapkit on iPhone.  For a current project I’ve been required to plot a location on a map so looked at a straight forward way to achieve what I was after.  Thankfully, iPhone makes it very easy to do this.

The following tutorial takes you through creating a project from scratch, which will plot a single point from latitude and longitude coordinates and zoom to that position.

Step 1 : Create the project

Okay, so lets start by creating a new project. Fire up XCode and choose File ->New Project and choose View-based Application.  Let’s call it Map and click on Save.  When the project opens up, expand the Classes and Resources groups because we’ll be using these later. It still bugs me that XCode puts boilerplate XIB files into Resources but newly created XIB files into the same directory…. one or the other I’d say!

Before we can use the MapKit we have to add the framework to our project.  Go to the Project menu and choose Edit Active Target Map.  Under the General tab, click the + button in the bottom pane to add a new framework.  Scroll down and choose MapKit.framework and then close the window.  Easy!

Step 2 : Add the MapView and wire it up

Open up MapViewController.h.  First of all we need to import the MapKit header and then create an instance variable which we will hook up in Interface Builder.  Modify your header so it looks like this…

#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
 
@interface MapViewController : UIViewController {
 
	MKMapView *mapView;
 
}
 
@property (nonatomic, retain) IBOutlet MKMapView *mapView;
 
@end

Next, open up MapViewController.xib in Interface Builder. From the Library window, drag over a MapView object into your view and let it fill the whole area. Right-click drag from File’s Owner to your new MKMapView object and choose mapView.

Finally, we need to make our class the delegate for the MapView. Right-click drag from the MKMapView object back to File’s Owner and choose delegate from the popup menu. You can now save and close Interface Builder. Excellent – we’re now wired up and ready to do some coding.

Step 3 : Adding the annotation class

Probably the easiest way to add an annotation to a MapView is to create a new class which conforms to the required MKAnnotation delegate.  Go to File -> New File and choose Objective-C class.  Make it a subclass of NSObject and click Next.  Lets call the new class MapViewAnnotation.  Make sure you’re also creating the .h file too and click Finish.

Open up MapViewAnnotation.h.  We are only going to add two instance variables.  One will hold the title of the annotated point.  The other will hold the coordinates of the point.  We will also create an initialiser to set those two variables whenever we create an instance of our object.   Modify your file to look like this…

#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
 
@interface MapViewAnnotation : NSObject <MKAnnotation> {
 
	NSString *title;
	CLLocationCoordinate2D coordinate;
 
}
 
@property (nonatomic, copy) NSString *title;
@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
 
- (id)initWithTitle:(NSString *)ttl andCoordinate:(CLLocationCoordinate2D)c2d;
 
@end

Now open up MapViewAnnotation.m.  Nothing spectacular is going on in here – we are simply initialising our instance variables.  Modify your file to look like this…

#import "MapViewAnnotation.h"
 
@implementation MapViewAnnotation
 
@synthesize title, coordinate;
 
- (id)initWithTitle:(NSString *)ttl andCoordinate:(CLLocationCoordinate2D)c2d {
	[super init];
	title = ttl;
	coordinate = c2d;
	return self;
}
 
- (void)dealloc {
	[title release];
	[super dealloc];
}
 
@end

That’s it for our annotation class.

Step 4 : Making it all work

At the moment, if you run your project it will display the map view but it won’t do much else. Not very exciting.  Let’s finish this and get your point plotted on that map.  While we’re at it, we should also centre in on that point so we can see it more clearly and zoom to a reasonable distance.  For the purposes of this tutorial I’m going to plot a point to Buckingham Palace, London, UK (because it’s big and obvious!).

Open up MapViewController.m.  In here we are going to add two main parts (both documented in the code below).  The first is our viewDidLoad method which will add our annotation to the mapView object.  The second is our method to zoom to the point when an annotation is added to the map (didAddAnnotationViews method).  Change your file to look like this…

#import "MapViewController.h"
#import "MapViewAnnotation.h"
 
@implementation MapViewController
 
@synthesize mapView;
 
// When the view loads
- (void)viewDidLoad
{
	// Set some coordinates for our position (Buckingham Palace!)
	CLLocationCoordinate2D location;
	location.latitude = (double) 51.501468;
	location.longitude = (double) -0.141596;
 
	// Add the annotation to our map view
	MapViewAnnotation *newAnnotation = [[MapViewAnnotation alloc] initWithTitle:@"Buckingham Palace" andCoordinate:location];
	[self.mapView addAnnotation:newAnnotation];
	[newAnnotation release];
}
 
// When a map annotation point is added, zoom to it (1500 range)
- (void)mapView:(MKMapView *)mv didAddAnnotationViews:(NSArray *)views
{
	MKAnnotationView *annotationView = [views objectAtIndex:0];
	id <MKAnnotation> mp = [annotationView annotation];
	MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance([mp coordinate], 1500, 1500);
	[mv setRegion:region animated:YES];
	[mv selectAnnotation:mp animated:YES];
}
 
// Received memory warning
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}
 
// If the view unloads, release the map view
- (void)viewDidUnload {
	[super viewDidUnload];
	[mapView release];
	mapView = nil;
}
 
// Deallocations
- (void)dealloc {
	[mapView release];
    [super dealloc];
}
 
@end

And that’s all there is to it.  Build and run your project and you should get a picture like the one at the start of this tutorial.  Not too tricky at all! Here’s the project file for those who just couldn’t be bothered copy / pasting!

Map Project Source Files
(Note: You must be logged in to download the file)

Leave a comment ?

30 Comments.

  1. how can i put a second annotation?

    thanks a lot!

  2. Under the part where the code adds the annotation view, just copy and paste to add additional annotations (obviously with different coordinates etc)…

    // Set up an object for our annotation
    MapViewAnnotation *newAnnotation;
     
    // Add the annotation to our map view
    newAnnotation = [[MapViewAnnotation alloc] initWithTitle:@"Buckingham Palace" andCoordinate:location];
    [self.mapView addAnnotation:newAnnotation];
    [newAnnotation release];
     
    // Another annotation added to map view!
    newAnnotation = [[MapViewAnnotation alloc] initWithTitle:@"A new title goes here" andCoordinate:differentLocationCoordsGoHere];
    [self.mapView addAnnotation:newAnnotation];
    [newAnnotation release];

    If you’ve got a lot of annotations, you could put them in a loop using a similar method.
    Hope that helps,
    Simon

  3. The map in the background should appear or not?

  4. Yes, it should be pretty much how it’s shown in the image at the top of the article.

  5. More Mapkit | - pingback on July 15, 2011 at 2:20 pm
  6. How can i show my current location instead of those below
    location.latitude = (double) 51.501468;
    location.longitude = (double) -0.141596;

    many thanks!!

  7. You’d need to use CoreLocation (CLLocationManager) to get this information. There are lots of tutorials on the web about this – search ‘iphone get current location coordinates’.

  8. 15 iPhone Application Development Tutorials Worth Checking Out - pingback on November 1, 2011 at 9:53 am
  9. hey- i’m trying to build a map app, and i’m curious what format the annotation needs to be in. I saw one tutorial where it was a plist, and then others that state xml. I have all the data in a txt file, but not sure how to format it properly.

  10. good

  11. @Bjackt : It depends how many annotations you’re talking about. If it’s a few, I’d make an array of annotation objects. If it’s loads, I’d use Core Data.

  12. Hi, your tutorial is great however how would i add more information to each of the annotations?

  13. @Simon: I want to create a map app that has multiple coordinate locations. I know that I need to create an array, but can you give me a basic idea what that would look like and does that go in the new object class that I created or does it go in the “ViewController” .h and .m?

  14. Hey the [super init] doesn’t func in Xcode 4.2 in the class MapViewAnnotaion.
    As failure comes: “The result of a delegate init call must be immediately returned or assigned to ‘self’”
    Can you help me?

  15. Hi, please, how can I call, callout (select) pin programmatically from different view controller? I have about 200 pins (annotations) in mapview and I would like to select a particular pin from detailTableViewController, where I have access to coordinates of pin that I want to select and zoom into its position in MkMapView.
    I think it should be the this method…SelectAnnotation:animated: ,but I don’t know how to use it…
    Thank you for any help! JAKUB

  16. This is a great tutorial and really helped me progress on a project I’m working on. Is it possible to add a disclosure button to the annotation so I can push segue to another view controller in a storyboard project?
    Thx!
    –bd–

  17. Really excellent tutorial, and an excellent one jump starters.. i was wondering can you post an example on who to link annotations with a Mysql database. in a sense that it will plot the values of the annotations on the map.
    this would be very helpful, as it will be taking the above example for a higher more practical level…

    thanks,

  18. Wi Fi Horizon, use copoun inside - pingback on February 25, 2013 at 7:08 pm
  19. Hi Simon. Thanks a lot for this tutorial! I found it really helpful in creating custom map annotations. I compiled a comprehensive list of top tutorials on map annotation for iOS. I included your post. Hope other developers can find it useful. Check it out/ feel free to share.
    http://www.verious.com/board/Giancarlo-Leonio/map-annotation-for-ios

  20. how to autoload annotation title? I mean without clicking the flag, title will popup itself.

  21. got it: [_mapView selectAnnotation:myAnnotation animated:YES];

  22. How can i add subtitle to my annotation ?

  23. ok i figure out , :smile:
    firstly you should change ur mapviewannot.h to
    @interface MapviewAnnotation : NSObject {
    NSString *title;
    CLLocationCoordinate2D coordinate;
    NSString *subtitle;
    }
    then add @property (nonatomic, copy) NSString *subtitle; to same .h file after that make newannotion.subtitle = @”whatever”; as extra line after you’re initwith title at mapviewcontroller.m

  24. Centering MKMapView on an annotation | Technology & Programming - pingback on November 10, 2013 at 4:54 am
  25. Hi Simon i downloaded your code and it works. thanks a lot. great job!!!.
    can you please advice how to setup the code in multiple storyboard apps. i have already started an app using Multiple storyboard and in one of the view controller i will need to show a map with our store locations pinned on the map. can you please help me out? Thanks

Leave a Comment