This is part of an ELC Tech Network

Introduction to MapKit in iPhone OS 3.0

Introduction

Hello everyone. Welcome to another screencast. Today we will be looking into the MapKit, a new API’s made available by Apple in the iPhone OS 3.0 release. The MapKit allows simple access to the map seen in the maps application. Using GoogleMaps as its engine the map kit allows for a developer to make their own custom map interface to fit their own application. Today we will be reviewing the MapView as well as the Map Annotations that can be used to highlight points of interest in a map. We will create our own custom map app, along with custom annotations. Let’s dive in.

Skill Level Intermediate

This tutorial is one for people familiar with general Objective C development and introductory experience to the iPhone SDK. Knowledge of general Interface Builder usage and DataSource and Delegate methods are required.

Screencast

I film myself coding out the entire sample project for each post. I personally think going through the Screencast is the best way to learn. But feel free to look through the slides and text if that suites you better.

Introduction to Map Kit on iPhone OS 3.0 from Collin Ruffenach on Vimeo.

Source

iCodeBlogMap Source

Tutorial

Introduction to MapKit on iPhone OS 3.001

Introduction to MapKit on iPhone OS 3.002

Introduction to MapKit on iPhone OS 3.003

Introduction to MapKit on iPhone OS 3.004

Introduction to MapKit on iPhone OS 3.005

Introduction to MapKit on iPhone OS 3.006

Introduction to MapKit on iPhone OS 3.007

Introduction to MapKit on iPhone OS 3.008

Introduction to MapKit on iPhone OS 3.009

Introduction to MapKit on iPhone OS 3.010

Introduction to MapKit on iPhone OS 3.011

Introduction to MapKit on iPhone OS 3.012

Introduction to MapKit on iPhone OS 3.013

Introduction to MapKit on iPhone OS 3.014

Introduction to MapKit on iPhone OS 3.015

Introduction to MapKit on iPhone OS 3.016

Introduction to MapKit on iPhone OS 3.017

Introduction to MapKit on iPhone OS 3.018

Introduction to MapKit on iPhone OS 3.019

Introduction to MapKit on iPhone OS 3.020

Introduction to MapKit on iPhone OS 3.021

Introduction to MapKit on iPhone OS 3.022

iCodeBlogMapViewController.h

#import "iCodeBlogAnnotation.h"
#import "iCodeBlogAnnotationView.h"
 
@interface iCodeMapViewController : UIViewController
{
	IBOutlet UITableView *tableview;
	IBOutlet MKMapView *mapView;
	IBOutlet UIImageView *shadowImage;
}
 
@property (nonatomic, retain) IBOutlet UITableView *tableview;
@property (nonatomic, retain) IBOutlet MKMapView *mapView;
@property (nonatomic, retain) IBOutlet UIImageView *shadowImage;
 
-(void)loadOurAnnotations;
 
@end

Introduction to MapKit on iPhone OS 3.023

iCodeBlogAnnoation.h

typedef enum {
	iCodeBlogAnnotationTypeApple = 0,
	iCodeBlogAnnotationTypeEDU = 1,
	iCodeBlogAnnotationTypeTaco = 2
} iCodeMapAnnotationType;
 
@interface iCodeBlogAnnotation : NSObject
{
	CLLocationCoordinate2D coordinate;
	NSString *title;
	NSString *subtitle;
	iCodeMapAnnotationType annotationType;
}
 
@property (nonatomic) CLLocationCoordinate2D coordinate;
@property (nonatomic, retain) NSString *title;
@property (nonatomic, retain) NSString *subtitle;
@property (nonatomic) iCodeMapAnnotationType annotationType;
 
@end

Introduction to MapKit on iPhone OS 3.024

Introduction to MapKit on iPhone OS 3.025

Introduction to MapKit on iPhone OS 3.026

Advertisement

iCodeBlogAnnoation.m

@implementation iCodeBlogAnnotation
 
@synthesize coordinate;
@synthesize title;
@synthesize subtitle;
@synthesize annotationType;
 
-init
{
	return self;
}
 
-initWithCoordinate:(CLLocationCoordinate2D)inCoord
{
	coordinate = inCoord;
	return self;
}
 
@end

Introduction to MapKit on iPhone OS 3.027

iCodeBlogAnnoationView.h

@interface iCodeBlogAnnotationView : MKAnnotationView
{
	UIImageView *imageView;
}
 
@property (nonatomic, retain) UIImageView *imageView;
 
@end

Introduction to MapKit on iPhone OS 3.028

Introduction to MapKit on iPhone OS 3.029

Introduction to MapKit on iPhone OS 3.030

Images to Use

AppleMarker

SchoolMarker

TacosMarker



iCodeBlogAnnoationView.m

#import "iCodeBlogAnnotationView.h"
 
@implementation iCodeBlogAnnotationView
 
@synthesize imageView;
 
#define kHeight 40
#define kWidth  37
#define kBorder 2
 
- (id)initWithAnnotation:(id )annotation reuseIdentifier:(NSString *)reuseIdentifier
{
	iCodeBlogAnnotation* myAnnotation = (iCodeBlogAnnotation*)annotation;
 
	if([myAnnotation annotationType] == iCodeBlogAnnotationTypeApple)
	{
		self = [super initWithAnnotation:myAnnotation reuseIdentifier:reuseIdentifier];
		self.frame = CGRectMake(0, 0, kWidth, kHeight);
		self.backgroundColor = [UIColor clearColor];
 
		imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"AppleMarker.png"]];
		imageView.frame = CGRectMake(kBorder, kBorder, kWidth - 2 * kBorder, kWidth - 2 * kBorder);
		[self addSubview:imageView];
	}
 
	else if([myAnnotation annotationType] == iCodeBlogAnnotationTypeEDU)
	{
		self = [super initWithAnnotation:myAnnotation reuseIdentifier:reuseIdentifier];
		self.frame = CGRectMake(0, 0, kWidth, kHeight);
		self.backgroundColor = [UIColor clearColor];
 
		imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"SchoolMarker.png"]];
		imageView.frame = CGRectMake(kBorder, kBorder, kWidth - 2 * kBorder, kWidth - 2 * kBorder);
		[self addSubview:imageView];
	}
 
	else if([myAnnotation annotationType] == iCodeBlogAnnotationTypeTaco)
	{
		self = [super initWithAnnotation:myAnnotation reuseIdentifier:reuseIdentifier];
		self.frame = CGRectMake(0, 0, kWidth, kHeight);
		self.backgroundColor = [UIColor clearColor];
 
		imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"TacosMarker.png"]];
		imageView.frame = CGRectMake(kBorder, kBorder, kWidth - 2 * kBorder, kWidth - 2 * kBorder);
		[self addSubview:imageView];
	}
 
	[imageView setContentMode:UIViewContentModeScaleAspectFill];
 
	return self;
}
 
@end

Introduction to MapKit on iPhone OS 3.031

Introduction to MapKit on iPhone OS 3.032

iCodeBlogMapViewController.m

-(void)loadOurAnnotations
{
	CLLocationCoordinate2D workingCoordinate;
 
	workingCoordinate.latitude = 40.763856;
	workingCoordinate.longitude = -73.973034;
	iCodeBlogAnnotation *appleStore1 = [[iCodeBlogAnnotation alloc] initWithCoordinate:workingCoordinate];
	[appleStore1 setTitle:@"Apple Store 5th Ave."];
	[appleStore1 setSubtitle:@"Apple's Flagship Store"];
	[appleStore1 setAnnotationType:iCodeBlogAnnotationTypeApple];
 
	[mapView addAnnotation:appleStore1];
 
	workingCoordinate.latitude = 51.514298;
	workingCoordinate.longitude = -0.141949;
	iCodeBlogAnnotation *appleStore2 = [[iCodeBlogAnnotation alloc] initWithCoordinate:workingCoordinate];
	[appleStore2 setTitle:@"Apple Store St. Regent"];
	[appleStore2 setSubtitle:@"London England"];
	[appleStore2 setAnnotationType:iCodeBlogAnnotationTypeApple];
 
	[mapView addAnnotation:appleStore2];
 
	workingCoordinate.latitude = 35.672284;
	workingCoordinate.longitude = 139.765702;
	iCodeBlogAnnotation *appleStore3 = [[iCodeBlogAnnotation alloc] initWithCoordinate:workingCoordinate];
	[appleStore3 setTitle:@"Apple Store Giza"];
	[appleStore3 setSubtitle:@"Tokyo, Japan"];
	[appleStore3 setAnnotationType:iCodeBlogAnnotationTypeApple];
 
	[mapView addAnnotation:appleStore3];
 
	workingCoordinate.latitude = 37.331741;
	workingCoordinate.longitude = -122.030564;
	iCodeBlogAnnotation *appleStore4 = [[iCodeBlogAnnotation alloc] initWithCoordinate:workingCoordinate];
	[appleStore4 setTitle:@"Apple Headquarters"];
	[appleStore4 setSubtitle:@"The Mothership"];
	[appleStore4 setAnnotationType:iCodeBlogAnnotationTypeApple];
 
	[mapView addAnnotation:appleStore4];
 
	workingCoordinate.latitude = 41.894518;
	workingCoordinate.longitude = -87.624005;
	iCodeBlogAnnotation *appleStore5 = [[iCodeBlogAnnotation alloc] initWithCoordinate:workingCoordinate];
	[appleStore5 setTitle:@"Apple Store Michigan Ave."];
	[appleStore5 setSubtitle:@"Chicago, IL"];
	[appleStore5 setAnnotationType:iCodeBlogAnnotationTypeApple];
 
	[mapView addAnnotation:appleStore5];
 
	workingCoordinate.latitude = 32.264977;
	workingCoordinate.longitude = -110.944011;
	iCodeBlogAnnotation *tacoShop1 = [[iCodeBlogAnnotation alloc] initWithCoordinate:workingCoordinate];
	[tacoShop1 setTitle:@"Nico's Taco Shop"];
	[tacoShop1 setSubtitle:@"Tucson, AZ"];
	[tacoShop1 setAnnotationType:iCodeBlogAnnotationTypeTaco];
 
	[mapView addAnnotation:tacoShop1];
 
	workingCoordinate.latitude = 32.743242;
	workingCoordinate.longitude = -117.181451;
	iCodeBlogAnnotation *tacoShop2 = [[iCodeBlogAnnotation alloc] initWithCoordinate:workingCoordinate];
	[tacoShop2 setTitle:@"Lucha Libre Gourmet"];
	[tacoShop2 setSubtitle:@"San Diego, CA"];
	[tacoShop2 setAnnotationType:iCodeBlogAnnotationTypeTaco];
 
	[mapView addAnnotation:tacoShop2];
 
	workingCoordinate.latitude = 32.594987;
	workingCoordinate.longitude = -117.060936;
	iCodeBlogAnnotation *tacoShop3 = [[iCodeBlogAnnotation alloc] initWithCoordinate:workingCoordinate];
	[tacoShop3 setTitle:@"El Ranchero Taco Shop"];
	[tacoShop3 setSubtitle:@"Rocky Pointe, Mexico"];
	[tacoShop3 setAnnotationType:iCodeBlogAnnotationTypeTaco];
 
	[mapView addAnnotation:tacoShop3];
 
	workingCoordinate.latitude = -34.594859;
	workingCoordinate.longitude = -58.384336;
	iCodeBlogAnnotation *tacoShop4 = [[iCodeBlogAnnotation alloc] initWithCoordinate:workingCoordinate];
	[tacoShop4 setTitle:@"Taco Tequila Sangria S.A."];
	[tacoShop4 setSubtitle:@"Buneos Aires, Argentina"];
	[tacoShop4 setAnnotationType:iCodeBlogAnnotationTypeTaco];
 
	[mapView addAnnotation:tacoShop4];
 
	workingCoordinate.latitude = 38.240550;
	workingCoordinate.longitude = -0.526509;
	iCodeBlogAnnotation *tacoShop5 = [[iCodeBlogAnnotation alloc] initWithCoordinate:workingCoordinate];
	[tacoShop5 setTitle:@"Albertsma Taco"];
	[tacoShop5 setSubtitle:@"Gran Alacant, Spain"];
	[tacoShop5 setAnnotationType:iCodeBlogAnnotationTypeTaco];
 
	[mapView addAnnotation:tacoShop5];	
 
	workingCoordinate.latitude = 33.419490;
	workingCoordinate.longitude = -111.930563;
	iCodeBlogAnnotation *school1 = [[iCodeBlogAnnotation alloc] initWithCoordinate:workingCoordinate];
	[school1 setTitle:@"Arizona State University"];
	[school1 setSubtitle:@"Go Sun Devils"];
	[school1 setAnnotationType:iCodeBlogAnnotationTypeEDU];
 
	[mapView addAnnotation:school1];
 
	workingCoordinate.latitude = 35.087537;
	workingCoordinate.longitude = -106.618184;
	iCodeBlogAnnotation *school2 = [[iCodeBlogAnnotation alloc] initWithCoordinate:workingCoordinate];
	[school2 setTitle:@"University of New Mexico"];
	[school2 setSubtitle:@"Go Lobos"];
	[school2 setAnnotationType:iCodeBlogAnnotationTypeEDU];
 
	[mapView addAnnotation:school2];
 
	workingCoordinate.latitude = 40.730838;
	workingCoordinate.longitude = -73.997498;
	iCodeBlogAnnotation *school3 = [[iCodeBlogAnnotation alloc] initWithCoordinate:workingCoordinate];
	[school3 setTitle:@"New York University"];
	[school3 setSubtitle:@"New York, NY"];
	[school3 setAnnotationType:iCodeBlogAnnotationTypeEDU];
 
	[mapView addAnnotation:school3];
 
	workingCoordinate.latitude = 51.753523;
	workingCoordinate.longitude = -1.253171;
	iCodeBlogAnnotation *school4 = [[iCodeBlogAnnotation alloc] initWithCoordinate:workingCoordinate];
	[school4 setTitle:@"Oxford University"];
	[school4 setSubtitle:@"Oxford, England"];
	[school4 setAnnotationType:iCodeBlogAnnotationTypeEDU];
 
	[mapView addAnnotation:school4];
 
	workingCoordinate.latitude = 22.131982;
	workingCoordinate.longitude = 82.142302;
	iCodeBlogAnnotation *school5 = [[iCodeBlogAnnotation alloc] initWithCoordinate:workingCoordinate];
	[school5 setTitle:@"India Institute of Technology"];
	[school5 setSubtitle:@"Delhi, India"];
	[school5 setAnnotationType:iCodeBlogAnnotationTypeEDU];
 
	[mapView addAnnotation:school5];
}

Introduction to MapKit on iPhone OS 3.033

iCodeblogMapViewController.m

- (iCodeBlogAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id )annotation
{
	iCodeBlogAnnotationView *annotationView = nil;
 
	// determine the type of annotation, and produce the correct type of annotation view for it.
	iCodeBlogAnnotation* myAnnotation = (iCodeBlogAnnotation *)annotation;
 
	if(myAnnotation.annotationType == iCodeBlogAnnotationTypeApple)
	{
		NSString* identifier = @"Apple";
		iCodeBlogAnnotationView *newAnnotationView = (iCodeBlogAnnotationView *)[self.mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
 
		if(nil == newAnnotationView)
		{
			newAnnotationView = [[[iCodeBlogAnnotationView alloc] initWithAnnotation:myAnnotation reuseIdentifier:identifier] autorelease];
		}
 
		annotationView = newAnnotationView;
	}
	else if(myAnnotation.annotationType == iCodeBlogAnnotationTypeEDU)
	{
		NSString* identifier = @"School";
 
		iCodeBlogAnnotationView *newAnnotationView = (iCodeBlogAnnotationView *)[self.mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
 
		if(nil == newAnnotationView)
		{
			newAnnotationView = [[[iCodeBlogAnnotationView alloc] initWithAnnotation:myAnnotation reuseIdentifier:identifier] autorelease];
		}
 
		annotationView = newAnnotationView;
	}
	else if(myAnnotation.annotationType == iCodeBlogAnnotationTypeTaco)
	{
		NSString* identifier = @"Taco";
 
		iCodeBlogAnnotationView *newAnnotationView = (iCodeBlogAnnotationView *)[self.mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
 
		if(nil == newAnnotationView)
		{
			newAnnotationView = [[[iCodeBlogAnnotationView alloc] initWithAnnotation:myAnnotation reuseIdentifier:identifier] autorelease];
		}
 
		annotationView = newAnnotationView;
	}
 
	[annotationView setEnabled:YES];
	[annotationView setCanShowCallout:YES];
 
	return annotationView;
}

Introduction to MapKit on iPhone OS 3.034

Introduction to MapKit on iPhone OS 3.035

iCodeBlogMapViewController.m

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 3;
}

Introduction to MapKit on iPhone OS 3.036

iCodeBlogMapViewController.m

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
	if(section == iCodeBlogAnnotationTypeApple)
	{
		return @"Apple Markers";
	}
 
	else if(section == iCodeBlogAnnotationTypeEDU)
	{
		return @"Schools";
	}
 
	else if(section == iCodeBlogAnnotationTypeTaco)
	{
		return @"Taco Shops";
	}
 
	return nil;
}

Introduction to MapKit on iPhone OS 3.037

iCodeBlogMapViewController.m

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
	return 5;
}

Introduction to MapKit on iPhone OS 3.038

Introduction to MapKit on iPhone OS 3.039

iCodeBlogMapViewController.m

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
 
	if (cell == nil)
	{
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }
 
	NSMutableArray *annotations = [[NSMutableArray alloc] init];
 
	if(indexPath.section == 0)
	{
		for(iCodeBlogAnnotation *annotation in [mapView annotations])
		{
			if([annotation annotationType] == iCodeBlogAnnotationTypeApple)
			{
				[annotations addObject:annotation];
			}
		}
 
		cell.textLabel.text = [[annotations objectAtIndex:indexPath.row] title];
	}
 
	else if(indexPath.section == 1)
	{
		for(iCodeBlogAnnotation *annotation in [mapView annotations])
		{
			if([annotation annotationType] == iCodeBlogAnnotationTypeEDU)
			{
				[annotations addObject:annotation];
			}
		}		
 
		cell.textLabel.text = [[annotations objectAtIndex:indexPath.row] title];
	}
 
	else if(indexPath.section == 2)
	{
		for(iCodeBlogAnnotation *annotation in [mapView annotations])
		{
			if([annotation annotationType] == iCodeBlogAnnotationTypeTaco)
			{
				[annotations addObject:annotation];
			}
		}
 
		cell.textLabel.text = [[annotations objectAtIndex:indexPath.row] title];
	}
 
    return cell;
}

Introduction to MapKit on iPhone OS 3.040

Introduction to MapKit on iPhone OS 3.041

iCodeBlogMapViewController.m

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
	for(iCodeBlogAnnotation *annotation in [mapView annotations])
	{
		if([[[[tableView cellForRowAtIndexPath:indexPath] textLabel] text] isEqualToString:[annotation title]])
		{
			[mapView setRegion:MKCoordinateRegionMake([annotation coordinate], MKCoordinateSpanMake(.01, .01)) animated:YES];
		}
	}
}
This entry was posted in Uncategorized and tagged , , , . Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

42 Comments

  1. Posted September 16, 2009 at 1:40 am | Permalink

    Nice post and good timing for me, thanks :-) Do you know if it’s currently possible to use your own map graphic, rather than use the standard satellite, hybrid, road graphics? I have a sneaking suspicion I’m going to have to “roll my own” map to support that, but if you know of a way to do it with the standard MapKit that would be great :-)

    Cheers!

  2. Andre
    Posted September 16, 2009 at 4:48 pm | Permalink

    I too am wondering the same thing. Is there any support for custom tiles and custom pin icons?

    How would one go about making their own map interface for small-sized maps?

  3. purplehairymonster
    Posted September 19, 2009 at 9:44 am | Permalink

    Thanks so much for this tutorial! It has been very useful and informative. Just wondering how would you go about showing only one country eg. France when the application loads? Thanks again :)

  4. Posted September 26, 2009 at 2:01 am | Permalink

    Excellent tutorial there, been playing around with my own custom annotations based upon this but I have been unable to implement the showUserLocation property since using this, any ideas as to why it would crash the application?

  5. Rich
    Posted September 27, 2009 at 9:17 am | Permalink

    Great tutorial!! Thanks!!

    I am wondering how a user and enter an actual address and have it translated into lay/long? If there is a MKReverseGeocoder, how come Apple did make a MKGoecoder class?

  6. Tom Biagioni
    Posted September 30, 2009 at 10:57 am | Permalink

    Exactly what I needed to move forward.

    I am having one problem though, i’m trying to modify the source to allow for user location, but I get this error:

    2009-09-30 09:54:10.374 iCodeMap[788:207] *** Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘*** -[MKUserLocation annotationType]: unrecognized selector sent to instance 0x4504b80′

    I’m thinking i need to allow for enter in a nil clause that allows for basic annotations to be displayed– or maybe just expand the enum– but i’m not sure how to do it.

    how can i change the MKUserLocation annotation?

  7. FF
    Posted October 6, 2009 at 4:24 am | Permalink

    Really wondering how the hell could i use “showUserLocation” without crashing…

  8. Mustafa
    Posted October 6, 2009 at 9:59 pm | Permalink

    Can you please make the screencast video available for download. Thanks.

  9. Posted October 8, 2009 at 4:00 am | Permalink

    Hello, thanks a lot for the tutorial. I am in a student in Ghana, I want to get the nearest distance to a marked annotation. Can anyone help me out?

  10. Carl Grainger
    Posted October 10, 2009 at 3:28 am | Permalink

    Another great screencast, making it all so easy. Definitely One to Watch. Big thanks for sharing your work.

  11. Posted October 16, 2009 at 6:44 am | Permalink

    I’m getting an error when I compile the delegate method for the mapView.

    - (iCodeBlogAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id )annotation {

    ///rest of code here…..
    }

    The error says: “Incompatible Objective-C types initializing ‘struct MKAnnotationView *’, expected ‘struct iCodeBlogAnnotationView *’

    The delegate method is called properly when the mapView is displayed, but because of this error crashes….

    any ideas from anyone??

  12. Posted October 16, 2009 at 10:42 am | Permalink

    Alright, I got past my last issue. Not entirely sure at this point, what I did….???? Oh well.

    Now the problem of the day, and it’s the same problem others have posted about.

    How to show the user location now, when you have that map delegate. When you apply the mapView.showUserLocation = YES; It goes into the mapView delegate you have us using, to use custom annotations, but it crashes when showing user location annotation. The error is what is reported by: Tom Biagioni & FF – above.

    Any help from anyone. When you have that delegate defined, it’s expecting you to pass in an annotation. When it’s called because you’ve got mapView.showUserLocation = YES; it is passing the wrong type of information…

    uncaught exception ‘NSInvalidArgumentException’, reason: ‘*** -[MKUserLocation annotationType]: unrecognized selector sent to instance

  13. Posted October 16, 2009 at 10:44 am | Permalink

    If you set the mapView.showUserLocation = YES; and you do not have the delegate method: – (iCodeBlogAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id )annotation

    everything works ok, except now we don’t get the custom annotation feature. How can we have our cake & eat it too?

  14. Tom Biagioni
    Posted October 18, 2009 at 9:47 pm | Permalink

    OK guys, I figured this out a while ago but totally forgot to post it, so here is the solution:

    step one: add the CoreLocation framework to the project.

    Step two: add this function to the iCodeMapViewController.m:


    - (void)setCurrentLocation:(CLLocation *)location {
    MKCoordinateRegion region = {{0.0f, 0.0f}, {0.0f, 0.0f}};
    region.center = location.coordinate;
    region.span.longitudeDelta = 0.15f;
    region.span.latitudeDelta = 0.15f;
    [self.mapView setRegion:region animated:YES];
    }

    step three: add this code to the ViewForAnnotation Method:


    if (annotation != mapView.userLocation) {
    //the rest of the ViewForAnnotation code goes here
    }else{
    CLLocation *location = [[CLLocation alloc]
    initWithLatitude:annotation.coordinate.latitude
    longitude:annotation.coordinate.longitude];
    [self setCurrentLocation:location];
    }

    you can change the setCurrentLocation method however you want, right now it is set to zoom in on the current location, which doesn’t seem all that helpful for this particular tutorial… but that should do it! hope it works for you!

  15. Posted October 19, 2009 at 5:09 am | Permalink

    hello Toni Biagioni, I have implemented your method for showing the current loaction of the user, but it gives me this error-”.objc_class_CCLocation”, referenced from:
    literal-pointer@__OBJC@__cls_refs@CLLocation in iCodeMapViewController.o

    please help

  16. Tom Biagioni
    Posted October 19, 2009 at 9:58 pm | Permalink

    @rinkart: you need to add the core location framework to your project

  17. Posted October 20, 2009 at 2:57 am | Permalink

    @Tom: I have tom, but have the same error.

  18. Posted October 20, 2009 at 3:18 am | Permalink

    @Tom: I did a clean, and IT WORKED, thanks. where is the current location set? I cant find it.

  19. Posted October 21, 2009 at 7:35 am | Permalink

    Nice Work! That did the trick. I guess the key was creating a condition where you wouldn’t be attempting to pass annotationType to the userLocation annotation.

    Thanks again! Watch out for the app – “Access My Library” coming soon! Allows you the ability to access all kinds of free material from your local library via your iphone/ipod touch.

  20. Posted October 26, 2009 at 3:02 am | Permalink

    @Tom: I have implemented the steps, i have no errors but still cannot see the user location.

  21. Tom Biagioni
    Posted October 29, 2009 at 11:55 am | Permalink

    @rinkart: it’s there, just hidden behind one of the annotations Collin added to the apple annotation type. comment out the following code and youll see it


    /*
    workingCoordinate.latitude = 37.331741;
    workingCoordinate.longitude = -122.030564;
    iCodeBlogAnnotation *appleStore4 = [[iCodeBlogAnnotation alloc] initWithCoordinate:workingCoordinate];
    [appleStore4 setTitle:@"Apple Headquarters"];
    [appleStore4 setSubtitle:@"The Mothership"];
    [appleStore4 setAnnotationType:iCodeBlogAnnotationTypeApple];

    [mapView addAnnotation:appleStore4];
    */

  22. Vishnu
    Posted October 31, 2009 at 5:03 am | Permalink

    Hi,

    Thanks for sharing your work. Great tutorial!!

    When I build the source code, the app opened as shown below. At the background I could see only a graph kind of pattern with pins(figures) and no map.

    /Users/308329/Desktop/Picture 2.png

    How do I get it right?

    Any help on this would be highly appreciated.

    Thanks in advance.

  23. Posted November 2, 2009 at 4:09 am | Permalink

    @Tom: thanks a lot for the help. i’ve seen the current location. I’ve implemented a parking space finder application with this. I have added options to change preferences of the mapview based on some selection criteria and i want to reload the map anytime a user selects any of these critiria. Can you pls offer help?

  24. Justin
    Posted November 7, 2009 at 11:28 am | Permalink

    Thanks for the video!

  25. Anonymous
    Posted November 16, 2009 at 5:02 pm | Permalink

    To get the built in user location to work simply do this:

    -(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id )annotation
    {
    	if ([annotation isKindOfClass:MKUserLocation.class]) return nil;
            //rest of code
    }
    
  26. ejpusa
    Posted November 17, 2009 at 12:59 pm | Permalink

    On adding the framework, you reference vs copy over. Is there a problem if you do click the check box and copy the framework?

    I always default to copy, so far no problems, just wondering what the rule of thumb is.

    thanks

  27. Danny
    Posted November 23, 2009 at 7:17 pm | Permalink

    Very awesome. Do you know if you can draw on a map? ie. mark a green line along a block for places you can park or something. Would I have to resort to using Quartz or something?

  28. Iphone Dev
    Posted December 10, 2009 at 12:00 am | Permalink

    Hi,

    This tutorial is very nice and saved my a lot.

    i need to do like when i press on AnnotationView and it should goes to detailed view of that result.

    I got method – (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control.

    but i dont know that what to do in that method. If anyone has done this then pls drop some code here.

    Thanks so much.

  29. Matteo
    Posted December 23, 2009 at 9:09 am | Permalink

    @Iphone Dev

    I think you need to set your annotation in this delegate’s function, like:

    - (MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id ) annotation{

    MKAnnotationView *annView = [mapView dequeueReusableAnnotationViewWithIdentifier:@"current loc"];
    annView=[[[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@”current loc”]autorelease];

    //this set your annotation to be tappable
    annView.canShowCallout = YES;

    //set the blue button on the right of the annotation
    annView.rightCalloutAccessoryView=[UIButton buttonWithType:UIButtonTypeDetailDisclosure];

    }
    //sorry for my bad english!!
    Bye!

  30. Harpreet
    Posted January 2, 2010 at 4:19 am | Permalink

    Very informative tutorial.

    I want to make a small random number generator app and wanted to know if there is a way to initiate an IBAction implicitly during the launch of the application.

    Thanks,
    Harpreet

  31. Digiguy
    Posted January 13, 2010 at 7:24 pm | Permalink

    Hi all,
    Great work on this.. .but I too am having some warning on build.
    - (iCodeBlogAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id )annotation
    {
    WARNING: INITIALIZATION FROM A DISTINCT OBJECTIVE C TYPE
    iCodeBlogAnnotationView *annotationView = nil;

    if (annotation != mapView.userLocation)
    WARNING: LOCAL DELARATION OF ‘MAPVIEW’ HIDES INSTANCE VARIABLE
    {
    //the rest of the ViewForAnnotation code goes here
    iCodeBlogAnnotation* myAnnotation = (iCodeBlogAnnotation *)annotation;
    if(myAnnotation.annotationType == iCodeBlogAnnotationTypeApple)
    {
    NSString* identifier = @”Apple”;
    iCodeBlogAnnotationView *newAnnotationView = (iCodeBlogAnnotationView *)[self.mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
    ………… rest of old code………
    }

    [annotationView setEnabled:YES];
    [annotationView setCanShowCallout:YES];
    }else{
    CLLocation *location = [[CLLocation alloc]
    initWithLatitude:annotation.coordinate.latitude
    longitude:annotation.coordinate.longitude];
    [self setCurrentLocation:location];
    }

    return annotationView;
    }
    It would be great if you could put all the mods here mentioned back into the source code. We would really appreciate it, and make a more complete tutorial, as the code isn’t working right, and hard to learn when it isn’t quite all there. Thanks guys… love the site!

    Sincerely,
    Kirk

  32. Digiguy
    Posted January 13, 2010 at 8:49 pm | Permalink

    … I have of course added the CoreLocation.Fraameworh Resources, cleaned run… still the errors.

    Sincerely,
    Kirk

  33. Rachel
    Posted January 15, 2010 at 12:19 pm | Permalink

    @Tom Biagioni

    I’m getting the same “Terminating app due to uncaught exception ‘NSInvalidArgumentException’…” error. I’m wondering if you ever managed to figure out the problem?

    Cheers,
    Rachel

  34. Abhishek
    Posted January 19, 2010 at 8:15 pm | Permalink

    hello very nice tutorial………,
    WhileYou being an iphone guru, i wanted ask you something.Do you know a GPS device that actually sends outs signals that the iphone can capture and convert it into latitudes and longitudes which u can use to track that device(using the Mapkit framework)?

  35. Yoot
    Posted February 3, 2010 at 7:16 am | Permalink

    Hi,

    thanks a lot for this tutorial, I’ve one problem though, in the MKMapView I can only see an empty grid, without any map displayed on it…

    Any idea of what’s going on ?

  36. Sam
    Posted February 3, 2010 at 9:15 pm | Permalink

    Hi there, Outstanding tutorial, totally helped to understand the mapkit, I got one problem, am trying to push to a view controller for each pin ?I already have abutton in each annotation with the title there,but it just cant go through! I will be so thankful if anyone helped me on this please.

  37. Sijo
    Posted February 26, 2010 at 4:18 pm | Permalink

    Can u help me in my problem.. I have to show 4 lines of data in that bubble..Like One title..then description, date, location name.. All the example showing only 2 lines of details. i tried like appending wanted data in subtitle and seperated by a \n character.. But it didnt worked.. Plz help me

  38. Wierboy
    Posted March 13, 2010 at 12:39 pm | Permalink

    I would also like to thank you for the very helpful tutorial!

    I am having a problem, however, in that everything seems to be working properly with the exception that I am still seeing red pins instead of my custom annotation view. No errors, compiles and runs perfectly.

    In the code snippet below, “It’s a bank” is being written to the log so this code is being called and the conditional is correctly identifying the fact that the annotation being added is of type MyAppAnnotationTypeBank. I also changed the tutorial’s clearColor to redColor in case the problem was with the image but I see no red background color.

    Any suggestions would be greatly appreciated!!

    Thanks!

    ——————————-

    - (id)initWithAnnotation:(id )annotation reuseIdentifier:(NSString *)reuseIdentifier {

    MyAppAnnotation *myAnnotation = (MyAppAnnotation*)annotation;

    if([myAnnotation annotationType] == MyAppAnnotationTypeBank) {
    NSLog(@”It’s a bank”);
    self = [super initWithAnnotation:myAnnotation reuseIdentifier:reuseIdentifier];
    self.frame = CGRectMake(0, 0, kHeight, kWidth);
    self.backgroundColor = [UIColor redColor];

    imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"bank.png"]];
    imageView.frame = CGRectMake(kBorder, kBorder, kWidth – 2 * kBorder, kHeight – 2 * kBorder);
    [self addSubview:imageView];
    } …

  39. Posted April 2, 2010 at 8:37 pm | Permalink

    Very good piece of content, this is very similar to a site that I have. Please check it out sometime and feel free to leave me a comenet on it and tell me what you think. Im always looking for feedback.

  40. teddafan
    Posted May 8, 2010 at 10:31 am | Permalink

    Hi,

    First, thank you very much for your very complete tutorial! I truly think it is the best around with the widest use of Mapkit.

    Could someone tell me how it would possible to list in the tableView the annotations in order of distance to the distance location?

    I thank you in advance for your help,

    Cheers

    teddafan

  41. eduardo
    Posted July 7, 2010 at 3:45 pm | Permalink

    Thanks GREAT TUTORIAL!!! The best!!!!

  42. lib
    Posted July 13, 2010 at 4:16 pm | Permalink

    Hi!! great tutorial but i was wondering i want the tableview be the full size of the window and also the map, do i need to create and extra xib for the tableview? or is other simple way posible? hope u can help me

    thanks

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">