I am new to iPhone programming and I can't understand why the MKAnnotationView is not showing the title's of my annotation's. Below is the code that is used to display it on the map.
- (void)mapView:(MKMapView *)mv didAddAnnotationViews:(NSArray *)views
{
NSLog(#"Entered didAddAnnotationViews");
MKAnnotationView *annotationView = [views objectAtIndex:0];
id <MKAnnotation> mp = [annotationView annotation];
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance([mp coordinate], 250, 250);
[mv setRegion:region animated:YES];
}
Here is where I am defining my annotations:
MapPoint *mp = [[MapPoint alloc]
initWithCoordinate:[newLocation coordinate]
title:[locationTitleField text]];
[mapView addAnnotation:mp];
[mp release];
mp is a class I have created to keep track of all the map points:
#import "MapPoint.h"
#implementation MapPoint
#synthesize coordinate, title;
- (id)initWithCoordinate:(CLLocationCoordinate2D)c title:(NSString *)t
{
[super init];
coordinate = c;
[self setTitle:t];
return self;
}
- (void)dealloc
{
[title release];
[super dealloc];
}
#end
I am beginner so go easy, and all help greatly appreciated.
Mike
Hi
did you look at apple "MapCallouts" example?
you can find it here -
http://developer.apple.com/library/ios/#samplecode/MapCallouts/Introduction/Intro.html
look at it and i would love to help if you have more questions.
shani
Related
Is there a way to load the MapView first then fill it with the annotations?
Reason why I ask: When I click on my map which calls my XML first to fill the annotations, there is a delay and only then does the View open with my MapView.
My concerns are that if the XML grows, it would delay even further or timeout.
See this code:
#import "MapViewController.h"
#import "MapViewAnnotation.h"
#implementation MapViewController
#synthesize mapView;
// When the view loads
- (void)viewDidLoad
{
[self performSelector:#selector(addAnnotation) withObject:#"" afterDelay:5.0];
}
//here i am delaying my annotation to 5 second so my map can first display
-(void)addAnnotation
{
// 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
I've created MKMapView and used UIBarButtonItem for zoom out to show all regions. It worked fine on iPhone Simulator but when I try on device it was zoom back to current location after 3-5 seconds or sometimes 10. I don't know what something wrong here. Thanks for any advice.
This following is my code
MapViewController.h
#import <UIKit/UIKit.h>
#import "MapListViewController.h"
#class MCLocation;
#interface MapViewController : UIViewController <MKMapViewDelegate, CLLocationManagerDelegate, MapListViewControllerDelegate>
{
CLLocationManager *locationManager;
NSArray *locations;
__weak IBOutlet MKMapView *worldView;
__weak IBOutlet UISegmentedControl *mapTypeControl;
}
#property (nonatomic, strong) MCLocation *item;
#property (nonatomic, strong) NSFetchedResultsController *fetchedResultsController;
#property (nonatomic, strong) NSManagedObjectContext *managedObjectContext;
- (IBAction)changeMapType:(id)sender;
- (void)zoomLocation:(CLLocationCoordinate2D)i;
#end
MapViewController.m
#import "MapViewController.h"
#import "MCLocation.h"
#import "MCLocationStore.h"
#import "MapDetailViewController.h"
#define METERS_PER_MILE 1609.344
#interface MapViewController ()
#end
#implementation MapViewController
#synthesize item;
#synthesize fetchedResultsController;
#synthesize managedObjectContext;
- (id)init
{
self = [super initWithNibName:#"MapViewController" bundle:nil];
if (self) {
[[self navigationItem] setTitle:#"Map"];
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:#"Back" style:UIBarButtonItemStyleBordered target:self action:nil];
[[self navigationItem] setBackBarButtonItem:backButton];
UIImage *userImage = [UIImage imageNamed:#"User.png"];
UIBarButtonItem *leftButton = [[UIBarButtonItem alloc] initWithImage:userImage style:UIBarButtonItemStyleBordered target:self action:#selector(showUser)];
UIImage *locationImage = [UIImage imageNamed:#"Pin.png"];
UIBarButtonItem *rightButton = [[UIBarButtonItem alloc] initWithImage:locationImage style:UIBarButtonItemStyleBordered target:self action:#selector(showLocation)];
[[self navigationItem] setLeftBarButtonItems:leftButton];
[[self navigationItem] setRightBarButtonItems:rightButton];
}
return self;
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
return [self init];
}
- (MKCoordinateRegion)regionForAnnotations:(NSArray *)annotations
{
MKCoordinateRegion region;
if ([annotations count] == 0) {
region = MKCoordinateRegionMakeWithDistance(worldView.userLocation.coordinate, 1000, 1000);
} else if ([annotations count] == 1) {
id <MKAnnotation> annotation = [annotations lastObject];
region = MKCoordinateRegionMakeWithDistance(annotation.coordinate, 1000, 1000);
} else {
CLLocationCoordinate2D topLeftCoord;
topLeftCoord.latitude = -90;
topLeftCoord.longitude = 180;
CLLocationCoordinate2D bottomRightCoord;
bottomRightCoord.latitude = 90;
bottomRightCoord.longitude = -180;
for (id <MKAnnotation> annotation in annotations)
{
topLeftCoord.latitude = fmax(topLeftCoord.latitude, annotation.coordinate.latitude);
topLeftCoord.longitude = fmin(topLeftCoord.longitude, annotation.coordinate.longitude);
bottomRightCoord.latitude = fmin(bottomRightCoord.latitude, annotation.coordinate.latitude);
bottomRightCoord.longitude = fmax(bottomRightCoord.longitude, annotation.coordinate.longitude);
}
MKCoordinateSpan span;
span.latitudeDelta = 2.0;
span.longitudeDelta = 0.5;
region.span = span;
region.center = worldView.userLocation.coordinate;
return [worldView regionThatFits:region];
}
- (IBAction)showUser
{
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(worldView.userLocation.coordinate, 250, 250);
[worldView setRegion:[worldView regionThatFits:region] animated:YES];
}
- (IBAction)showLocation
{
MKCoordinateRegion region = [self regionForAnnotations:locations];
[worldView setRegion:region animated:YES];
}
- (void)updateLocations
{
if (locations != nil) {
[worldView removeAnnotations:locations];
}
locations = [self.fetchedResultsController fetchedObjects];
[worldView addAnnotations:locations];
}
- (void)zoomLocation:(CLLocationCoordinate2D)i
{
CLLocationCoordinate2D zoomLocation = i;
MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(zoomLocation, 0.5*METERS_PER_MILE, 0.5*METERS_PER_MILE);
MKCoordinateRegion adjustedRegion = [worldView regionThatFits:viewRegion];
[worldView setRegion:adjustedRegion animated:YES];
}
- (void)performFetch
{
NSError *error;
if (![self.fetchedResultsController performFetch:&error]) {
FATAL_CORE_DATA_ERROR(error);
return;
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
[worldView setShowsUserLocation:YES];
[self performFetch];
[self loadMapTypePref];
[self updateLocations];
// If we have locations, then show them on the map. If there are no
// locations, then let the map view figure out how to center on the
// user's position. It will usually do a pretty good job.
if ([locations count] > 0) {
[self showLocation];
}
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
[mapTypeControl setHidden:YES];
CLLocationCoordinate2D coord = [item coordinate];
[worldView setCenterCoordinate:coord animated:NO];
[self zoomLocation:coord];
}
}
- (void)viewDidUnload
{
worldView = nil;
mapTypeControl = nil;
locations = nil;
fetchedResultsController = nil;
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc
{
[locationManager setDelegate:nil];
}
#pragma mark - MKMapViewDelegate
- (void)mapView:(MKMapView *)mapView
didUpdateUserLocation:(MKUserLocation *)userLocation
{
CLLocationCoordinate2D loc = [userLocation coordinate];
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(loc, 250, 250);
[worldView setRegion:region animated:YES];
}
- (MKAnnotationView *)mapView:(MKMapView *)mapView
viewForAnnotation:(id<MKAnnotation>)annotation
{
static NSString *LocationIdentifier = #"Location";
MKPinAnnotationView *annotationView = (MKPinAnnotationView *)[worldView dequeueReusableAnnotationViewWithIdentifier:LocationIdentifier];
if ([annotation isKindOfClass:[MCLocation class]]) {
if (!annotationView) {
annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:LocationIdentifier];
}
[annotationView setAnnotation:annotation];
[annotationView setPinColor:MKPinAnnotationColorRed];
[annotationView setEnabled:YES];
[annotationView setAnimatesDrop:YES];
[annotationView setCanShowCallout:YES];
[annotationView setCalloutOffset:CGPointMake(-5, 5)];
[annotationView setUserInteractionEnabled:YES];
UIButton *rightButton = nil;
UIImage *logoImage = [UIImage imageNamed:#"monkcup-map-pin.png.png"];
UIImageView *leftButton = [[UIImageView alloc] initWithImage:logoImage];
rightButton = [UIButton buttonWithType:UIButtonTypeInfoLight];
[annotationView setRightCalloutAccessoryView:rightButton];
[annotationView setLeftCalloutAccessoryView:leftButton];
return annotationView;
} else {
[[worldView userLocation] setTitle:#"You're here"];
}
return nil;
}
- (void)mapView:(MKMapView *)mapView
annotationView:(MKAnnotationView *)view
calloutAccessoryControlTapped:(UIControl *)control
{
// Call out code
}
#pragma mark - CLLocationManagerDelegate
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
NSTimeInterval t = [[newLocation timestamp] timeIntervalSinceNow];
if (t < -180) {
return;
}
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
//
}
#pragma mark - Fetched results controller
- (NSFetchedResultsController *)fetchedResultsController
{
if (fetchedResultsController) {
return fetchedResultsController;
}
// Create and configure a fetch request with the Book entity.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
MCLocationStore *ls = [MCLocationStore sharedStore];
self.managedObjectContext = ls.context;
NSEntityDescription *entity = [NSEntityDescription entityForName:#"MCLocation" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
// Create the sort descriptors array.
NSSortDescriptor *sd = [NSSortDescriptor sortDescriptorWithKey:#"storeName" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObjects:sd, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
// Create and initialize the fetch results controller.
fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:#"MapView"];
return fetchedResultsController;
}
#end
You've implemented the map view's didUpdateUserLocation delegate method and in there you are zooming the map to the user's location.
That delegate method will get called whenever the device gets a location update.
So after you zoom or pan away, if there's another location update, the delegate method gets called and it zooms back to the user location.
One option is to keep a boolean ivar (say didZoomToUserLocation) and in that method, you should only zoom (ie. call setRegion) if the flag is NO. Set the flag to YES in that method after calling setRegion.
In iOS 5 and up, you could also try setting the userTrackingMode to MKUserTrackingModeFollow instead of manually zooming. I think that mode gives the user some freedom to pan around while still following the user.
While my end project is not another where did I park app. I thought this would be a good place to start to get a good grasp of MKMap and Locations.
Ok so I can set pins, see myself, and get my current location to show up in a label.
What I can't do is:
A. On a button push
1) Store the users current location.
2) Drop a pin(red) in the current users location.
(So the new pin stays even if the user(blue) moves)
B. On a separate button push
1) Clear the pin of the users dropped pin(red) off the map.
I cannot seem to set the map annotation for the new pin in the button. The numbers change and the map does not refresh(i'm guessing) to show my pin with or with out the right set of coords in it.
This what I have so far. (NO SNICKERING) :P
#import "Find_My_CarViewController.h"
#import "MapAnnotation.h"
#implementation Find_My_CarViewController
#synthesize CLController;
#synthesize hereIamLat;
#synthesize hereIamLong;
#synthesize mapView;
- (void)dealloc
{
[hereIamLat release];
[hereIamLong release];
[CLController release];
[super dealloc];
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
[super viewDidLoad];
CLController = [[CoreLocationController alloc] init];
CLController.delegate = self;
[CLController.locMgr startUpdatingLocation];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
-(void)viewWillAppear:(BOOL)animated
{
MKCoordinateRegion region;
region.center.latitude =40.798356;
region.center.longitude= -81.411158;
region.span.longitudeDelta=0.3;
region.span.latitudeDelta =0.3;
[mapView setRegion:region animated:YES];
}
- (void)locationUpdate:(CLLocation *)location
{
latitudeLabel.text = [NSString stringWithFormat:#"LATITUDE: %f", location.coordinate.latitude];
longitudeLabel.text = [NSString stringWithFormat:#"LONGITUDE: %f", location.coordinate.longitude];
//hereIamLat = [NSString stringWithFormat:#"%g", location.coordinate.latitude];
//hereIamLong = [NSString stringWithFormat:#"%g", location.coordinate.longitude];
}
- (void)locationError:(NSError *)error
{
//speedLabel.text = [error description];
}
-(IBAction)PushToMark
{
NSScanner *strLat = [NSScanner scannerWithString:latitudeLabel.text];
double dblLat;
[strLat scanDouble:&dblLat];
NSScanner *strLong = [NSScanner scannerWithString:longitudeLabel.text];
double dblLong;
[strLong scanDouble:&dblLong];
NSLog(#"lat: %f",dblLat);
NSLog(#"long: %f",dblLong);
MKCoordinateRegion location1;
location1.center.latitude =dblLat;
location1.center.longitude= dblLong;
location1.span.longitudeDelta=0.1;
location1.span.latitudeDelta =0.1;
MapAnnotation *ann1 =[[[MapAnnotation alloc] init] autorelease];
ann1.title=#"Here";
ann1.subtitle=#"I AM";
ann1.coordinate= location1.center;
[mapView addAnnotation:ann1];
}
#end
Edit:
Ok so I went this route thanks.
#import "LocationTestViewController.h"
#import "CoreLocation/CoreLocation.h"
#import "MapAnnotation.h"
#implementation LocationTestViewController
#synthesize locationManager;
#synthesize mapView;
- (void)dealloc
{
[mapView release];
[locationManager release];
[super dealloc];
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
/*
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
[super viewDidLoad];
}
*/
- (void)viewDidUnload
{
[self setMapView:nil];
[self setLocationManager:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (IBAction)getLocation:(id)sender {
locationManager = [[CLLocationManager alloc] init];
locationManager.distanceFilter=kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
[locationManager startUpdatingLocation];
[mapView setMapType:MKMapTypeStandard];
[mapView setZoomEnabled:YES];
[mapView setScrollEnabled:YES];
MKCoordinateRegion region = {{0.0,0.0},{0.0,0.0}};
region.center.latitude = locationManager.location.coordinate.latitude;
region.center.longitude = locationManager.location.coordinate.longitude;
region.span.longitudeDelta = 0.005f;
region.span.latitudeDelta = 0.005f;
[mapView setRegion:region animated:YES];
[mapView setDelegate:sender];
MKCoordinateRegion location1;
location1.center.latitude =locationManager.location.coordinate.latitude;
location1.center.longitude= locationManager.location.coordinate.longitude;
location1.span.longitudeDelta=0.1;
location1.span.latitudeDelta =0.1;
MapAnnotation *ann1 =[[[MapAnnotation alloc] init] autorelease];
ann1.title=#"You Parked Here";
ann1.subtitle=#"";
ann1.coordinate= location1.center;
[mapView addAnnotation:ann1];
}
#end
Why not use a CLLocationCoordinate2D to store your current location when you get the delegate callback - (void)locationUpdate:(CLLocation *)location ? There's no real reason to use an MKCoordinateRegion and NSScanner.
Do this instead:
- (void)locationUpdate:(CLLocation *)location
{
latitudeLabel.text = [NSString stringWithFormat:#"LATITUDE: %f", location.coordinate.latitude];
longitudeLabel.text = [NSString stringWithFormat:#"LONGITUDE: %f", location.coordinate.longitude];
self.myLocation = location; // a property that stores the current location
}
Then in your - (IBAction)pushToMark you can create and add the annotation using self.myLocation as the coordinate property.
As for removing the annotation - see Mundi's answer for that.
Store a reference to your created annotation in a #property of your view controller. To remove, use
[mapView removeAnnotation:self.ann1];
self.ann1 = nil;
Also, your strategy to scan the string in the labels to find out the coordinate is also rather odd. Why not just use the location, which you can also store in a variable?
I have been trying to get multiple map pins to show on the map but it is not working. Can anyone help me out? I am using the code below:
- (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];
}
- (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];
}
Did you set the mapview delegate?
self.mapView.delegate = self;
Very new to xcode and somewhat confused. I was able to use a custom image for annotation - works fine. Problem is that I want to do is have a different images for each of the annotations. What should I add/change to the code below? Thanks in advance and remember, I'm a newbee!
#import "MapViewController.h"
#interface AddressAnnotation : NSObject<MKAnnotation> {
CLLocationCoordinate2D coordinate;
NSString *mTitle;
NSString *mSubTitle;
UIImage *image;
}
#property (nonatomic, retain) UIImage *image;
#end
#implementation AddressAnnotation
#synthesize coordinate;
#synthesize image;
- (NSString *)subtitle{
return mSubTitle;
}
- (NSString *)title{
return mTitle;
}
-(id)initWithCoordinate:(CLLocationCoordinate2D) c Title: (NSString *)title SubTitle: (NSString *) subTitle{
coordinate=c;
mTitle = [title retain];
mSubTitle = [subTitle retain];
NSLog(#"%f,%f",c.latitude,c.longitude);
return self;
}
-(void) dealloc{
[super dealloc];
[mTitle release];
[mSubTitle release];
}
#end
#implementation MapViewController
// The designated initializer. Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
/*
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization.
}
return self;
}
*/
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
//------ To Set center of the map ------
CLLocationCoordinate2D center;
center.latitude = 37.83792;
center.longitude = -122.247865;
MKCoordinateRegion region;
MKCoordinateSpan span;
span.latitudeDelta = 0.05;
span.longitudeDelta = 0.05;
region.center = center;
region.span = span;
[mapView setRegion:region animated:YES];
//------ To Add a point of interest ------
CLLocationCoordinate2D c1;
// Point one
c1.latitude = 37.8393624;
c1.longitude = -122.2436549;
AddressAnnotation* ad1 = [[AddressAnnotation alloc] initWithCoordinate:c1 Title:#"title here" SubTitle:#"subtitle here"];
ad1.image = [UIImage imageNamed:#"img01.png"];
[mapView addAnnotation:ad1];
[ad1 release];
// Point two
c1.latitude = 37.835964;
c1.longitude = -122.250538;
AddressAnnotation* ad2 = [[AddressAnnotation alloc] initWithCoordinate:c1 Title:#"title here" SubTitle:#"subtitle here"];
ad2.image = [UIImage imageNamed:#"img02.png"];
[mapView addAnnotation:ad2];
[ad2 release];
// Point three
c1.latitude = 37.8317039;
c1.longitude = -122.2454169;
AddressAnnotation* ad3 = [[AddressAnnotation alloc] initWithCoordinate:c1 Title:#"title here" SubTitle:#"subtitle here"];
ad3.image = [UIImage imageNamed:#"img03.png"];
[mapView addAnnotation:ad3];
[ad3 release];
//----------------------------------------
}
- (MKAnnotationView *)mapView:(MKMapView *)theMapView viewForAnnotation:(id <MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[AddressAnnotation class]])
{
static NSString *AnnotationIdentifier = #"AnnotationIdentifier";
MKPinAnnotationView *pinView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:AnnotationIdentifier];
if (!pinView)
{
pinView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationIdentifier] autorelease];
pinView.canShowCallout = YES;
pinView.animatesDrop = YES;
}
else
{
pinView.annotation = annotation;
}
UIImageView *leftCalloutView = [[UIImageView alloc]
initWithImage:((AddressAnnotation *)annotation).image];
pinView.leftCalloutAccessoryView = leftCalloutView;
[leftCalloutView release];
return pinView;
}
return nil;
}
/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations.
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc. that aren't in use.
}
- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[super dealloc];
}
#end
To display your own image instead of the standard pin, create a plain MKAnnotationView instead of a MKPinAnnotationView and set its image property instead of the leftCalloutAccessoryView:
- (MKAnnotationView *)mapView:(MKMapView *)theMapView viewForAnnotation:(id <MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[AddressAnnotation class]])
{
static NSString *AnnotationIdentifier = #"AnnotationIdentifier";
MKAnnotationView *pinView = [mapView dequeueReusableAnnotationViewWithIdentifier:AnnotationIdentifier];
if (!pinView)
{
pinView = [[[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationIdentifier] autorelease];
pinView.canShowCallout = YES;
}
else
{
pinView.annotation = annotation;
}
pinView.image = ((AddressAnnotation *)annotation).image;
return pinView;
}
return nil;
}
Note that the MKAnnotationView class doesn't have an animatesDrop property like MKPinAnnotationView so the annotations won't drop on the map. If a drop animation is required, it will have to be done manually (eg. in didAddAnnotationViews).