Search This Blog

Jan 15, 2011

How to place Animated Annotations on iPhone MapKit ?

This examples shows how to place animated annotation on iPhone Map. You can also get Coordinates of the places where you drop the annotation.

You can download source code from here Download.

Code for .h file.


@interface RootViewController : UIViewController {
    IBOutlet MKMapView *mapView;
    MKReverseGeocoder *reverseGeocoder;

@property (nonatomic, retain) MKReverseGeocoder *reverseGeocoder;
@property (nonatomic, retain) MKMapView *mapView;


Code for .m file.

#import "RootViewController.h"
#import "DDAnnotation.h"
#import "DDAnnotationView.h"

@interface RootViewController ()
- (void)coordinateChanged_:(NSNotification *)notification;

@implementation RootViewController
@synthesize reverseGeocoder, mapView;

NSMutableArray* arrNotification;

- (void)viewDidLoad {
    [super viewDidLoad];

    arrNotification = [[NSMutableArray alloc]init];
    CLLocationCoordinate2D theCoordinate;
    theCoordinate.latitude = 26.926;
    theCoordinate.longitude = 75.8235;
    MKCoordinateRegion region; = theCoordinate;
    MKCoordinateSpan span;
    span.latitudeDelta = 0.005;
    span.longitudeDelta = 0.005;
    [mapView setRegion:region animated:TRUE];
    DDAnnotation *annotation = [[[DDAnnotation alloc] initWithCoordinate:theCoordinate addressDictionary:nil] autorelease];
    annotation.title = @"Drag to Move Pin";
    annotation.subtitle = @"Tripolia Bazar, Biseswarji, Pink City, Jaipur, Rajasthan, India";
    [self.mapView addAnnotation:annotation];

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    return YES;

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(coordinateChanged_:) name:@"DDAnnotationCoordinateDidChangeNotification" object:nil];

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"DDAnnotationCoordinateDidChangeNotification" object:nil];   

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];

- (void)viewDidUnload {
    self.mapView.delegate = nil;
    self.mapView = nil;

- (void)dealloc {
    mapView.delegate = nil;
    [mapView release];
    [super dealloc];

#pragma mark -
#pragma mark DDAnnotationCoordinateDidChangeNotification

- (void)coordinateChanged_:(NSNotification *)notification {
    [arrNotification addObject:notification.object];
    DDAnnotation *annotation = notification.object;
    self.reverseGeocoder =
    [[[MKReverseGeocoder alloc] initWithCoordinate:annotation.coordinate] autorelease];
    reverseGeocoder.delegate = self;
    [reverseGeocoder start];   

#pragma mark -
#pragma mark MKMapViewDelegate

- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFailWithError:(NSError *)error
    NSString *errorMessage = [error localizedDescription];
    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Cannot obtain address."
    [alertView show];
    [alertView release];

- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFindPlacemark:(MKPlacemark *)placemark{
    DDAnnotation *annotation = [arrNotification objectAtIndex:0];
    NSDictionary *dictAddress = placemark.addressDictionary;
    NSString *strAddress = [NSString stringWithFormat:@"%@", [dictAddress objectForKey:@"FormattedAddressLines"]];
    strAddress = [strAddress stringByReplacingOccurrencesOfString:@"(" withString:@""];
    strAddress = [strAddress stringByReplacingOccurrencesOfString:@")" withString:@""];
    strAddress = [strAddress stringByReplacingOccurrencesOfString:@"\"" withString:@""];
    strAddress = [strAddress stringByReplacingOccurrencesOfString:@"  " withString:@""];
    strAddress = [strAddress stringByReplacingOccurrencesOfString:@"\n" withString:@" "];
    annotation.subtitle = [NSString    stringWithFormat:@"%@", strAddress];
    [arrNotification removeLastObject];

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)annotationView didChangeDragState:(MKAnnotationViewDragState)newState fromOldState:(MKAnnotationViewDragState)oldState {
    if (oldState == MKAnnotationViewDragStateDragging) {
        DDAnnotation *annotation = (DDAnnotation *)annotationView.annotation;
        annotation.subtitle = [NSString    stringWithFormat:@"%f %f", annotation.coordinate.latitude, annotation.coordinate.longitude];       

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id )annotation {
    if ([annotation isKindOfClass:[MKUserLocation class]]) {
        return nil;       
    static NSString * const kPinAnnotationIdentifier = @"PinIdentifier";
    MKAnnotationView *draggablePinView = [self.mapView dequeueReusableAnnotationViewWithIdentifier:kPinAnnotationIdentifier];
    if (draggablePinView) {
        draggablePinView.annotation = annotation;
    else {
        draggablePinView = [DDAnnotationView annotationViewWithAnnotation:annotation reuseIdentifier:kPinAnnotationIdentifier mapView:self.mapView];
        if ([draggablePinView isKindOfClass:[DDAnnotationView class]]) {
        else {
    return draggablePinView;



  1. Thanks for the post. You seem to know a bit about MapKit. Do you think it's possible to use MapKit as the basis for animating a layer on top of it? For example, could you use MapKit to display a map of a person's current location and then allow them to trace a colored line from point A to point B ensuring that they stay on roads? Or use it to show an animated car randomly roaming around the streets of a random map?



  2. Thanks for the post. I found it really useful. I compiled a list of top tutorials on ways to add custom annotations to the MapView control. I included your post. Check it out/ feel free to share. Hope other developers find it useful too :)