I am new with MapKit and all its functionalities and therefore, stuck at trying to display a pin. I followed an online video tutorial on how to find user current location and drop a pin there. But when I typed the method for the pin, I do not get it at all. I would like to know where did I go wrong for this.
- (void)viewDidLoad{
[super viewDidLoad];
self.title = #"Location";
mapView.showsUserLocation = YES;
self.locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
[locationManager startUpdatingHeading];
}
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{
NSLog(#"Annotation view run");
MKPinAnnotationView *pin = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"currentloc"];
pin.animatesDrop = YES;
return pin;
}
-(void) locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{
// once location is determined, center to that location.
location = newLocation.coordinate;
MKCoordinateRegion region;
region.center = location;
MKCoordinateSpan span;
span.latitudeDelta = 0.003;
span.longitudeDelta = 0.003;
region.span = span;
[mapView setRegion:region animated:FALSE];
}
Any advice of where I done wrong would be great!
As your method is never got invoked, you should do:
- (void)mapView:(MKMapView *)aMapView regionDidChangeAnimated:(BOOL)animated {
[aMapView removeAnnotation:[self point]];
mkShape.coordinate = aMapView.centerCoordinate;
[aMapView addAnnotation:mkShape];
}
And you should create your MKAnnotationView properly.
You need create two properties in .h file first (for performance reason):
MKPointAnnotation *mkShape;
MKAnnotationView *annotationView;
then use the code below to create your MKPointAnnotation
- (void)createShape
{
if (!mkShape) {
mkShape = [[MKPointAnnotation alloc] init];
mkShape.title = nil;
mkShape.subtitle = #"test description";
}
}
- (id <MKAnnotation>)point
{
[self createShape];
// Make sure to check if this is an MKPointAnnotation. MKOverlays also
// conform to MKAnnotation, so it isn't sufficient to just check to
// conformance to MKAnnotation.
if ([mkShape isKindOfClass:[MKPointAnnotation class]])
return (id <MKAnnotation>)mkShape;
return nil;
}
- (MKAnnotationView *)annotationView
{
if (!annotationView) {
id <MKAnnotation> annotation = [self point];
if (annotation) {
MKPinAnnotationView *pin =
[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:nil];
pin.canShowCallout = YES;
pin.animatesDrop = YES;
pin.draggable = NO;
annotationView = pin;
}
}
return annotationView;
}
- (MKAnnotationView *)mapView:(MKMapView *)aMapView viewForAnnotation:(id <MKAnnotation>)annotation
{
if ([annotation isEqual:mkShape]) {
return [self annotationView];
}
return nil;
}
At the end, don't forget to release your properties.
- (void)dealloc
{
[annotationView release];
[mkShape release];
[super dealloc];
}
Related
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.
I want to design a dynamic pin annotation on Google map in iPhone such that user can drag the pin by taping on it and place this pin on Google maps to set the location of its choice. After user puts the pin I want to get the location coordinates and location name corresponding to that pin.
Any suggestion how to develop this in iPhone.Thanks
In your view controller you have to implement methods from MKMapViewDelegate protocol and LongPressGestureAware (which I created) for dropping the pin on the map when the user taps and hold on the screen.
Your annotation should implement MKAnnotation and MKReverseGeocoderDelegate protocols.
I paste some of my code which can help you:
SimpleMapAnnotationViewController.h:
#interface SimpleMapAnnotationViewController : TTViewController<LongPressGestureAware, MKMapViewDelegate> {
SimpleMapAnnotation *_dropPin;
MKPinAnnotationView *_pinView;
}
SimpleMapAnnotationViewController.m :
#pragma mark -
#pragma mark LongPressGestureAware
-(void) initLongPressGestureRecognizer {
UILongPressGestureRecognizer *longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(handleLongPressGesture:)];
[self.map addGestureRecognizer:longPressGesture];
[longPressGesture release];
}
-(void)handleLongPressGesture:(UIGestureRecognizer*)sender {
if([sender isMemberOfClass:[UILongPressGestureRecognizer class]] && (sender.state == UIGestureRecognizerStateEnded || sender.state == UIGestureRecognizerStateBegan)) {
[self.map removeGestureRecognizer:sender]; //avoid multiple pins to appear when holding on the screen
}
CGPoint point = [sender locationInView:self.map];
CLLocationCoordinate2D theCoordinate = [self.map convertPoint:point toCoordinateFromView:self.map];
self.dropPin = [[[SimpleMapAnnotation alloc] initWithCoordinate:theCoordinate] autorelease];
[self.map addAnnotation:self.dropPin];
[self performSelector:#selector(selectInitialAnnotation) withObject:nil afterDelay:0.5];
}
-(void)selectInitialAnnotation {
[self.map selectAnnotation:[self.map.annotations objectAtIndex:0] animated:YES];
}
#pragma mark -
#pragma mark MKMapViewDelegate
- (MKAnnotationView *) mapView: (MKMapView *) mapView viewForAnnotation: (id<MKAnnotation>) annotation {
if (annotation == self.map.userLocation){
return nil; //default to blue dot
}
MKPinAnnotationView *pin = (MKPinAnnotationView *) [mapView dequeueReusableAnnotationViewWithIdentifier: #"annotation_ID"];
if (pin == nil) {
pin = [[[MKPinAnnotationView alloc] initWithAnnotation: annotation reuseIdentifier: #"annotation_ID"] autorelease];
} else {
pin.annotation = annotation;
}
pin.canShowCallout = YES;
pin.draggable = YES;
pin.animatesDrop = YES;
pin.pinColor = MKPinAnnotationColorGreen;
self.pinView = pin;
self.dropPin.pinView = self.pinView;
return pin;
}
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)annotationView didChangeDragState:(MKAnnotationViewDragState)newState fromOldState:(MKAnnotationViewDragState)oldState {
//NSArray *annotations = self.map.annotations;
if (oldState == MKAnnotationViewDragStateDragging) {
SimpleMapAnnotation *annotation = (SimpleMapAnnotation *)annotationView.annotation;
[annotation updateSubtitle];
}
if(newState == MKAnnotationViewDragStateEnding) {
NSLog(#"drag finish");
}
}
SimpleMapAnnotation.h
#interface SimpleMapAnnotation : NSObject <MKAnnotation, MKReverseGeocoderDelegate> {
CLLocationCoordinate2D _coordinate;
NSString *_title;
NSString *_subtitle;
MKPinAnnotationView *_pinView;
}
SimpleMapAnnotation.m
- (id)initWithCoordinate:(CLLocationCoordinate2D)coordinate {
self.coordinate = coordinate;
MKReverseGeocoder *geoCoder = [[MKReverseGeocoder alloc] initWithCoordinate:self.coordinate];
geoCoder.delegate = self;
[geoCoder start];
self.subtitle = [NSString stringWithFormat:#"%f %f", self.coordinate.latitude, self.coordinate.longitude];
return self;
}
#pragma mark -
#pragma mark MKReverseGeocoderDelegate
// this delegate is called when the reverseGeocoder finds a placemark
- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFindPlacemark:(MKPlacemark *)placemark
{
MKPlacemark * myPlacemark = placemark;
NSString *address = [myPlacemark.addressDictionary objectForKey:(NSString*) kABPersonAddressStreetKey];
self.title = address;
}
// this delegate method is called if an error occurs in locating your current location
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
NSLog(#"locationManager:%# didFailWithError:%#", manager, error);
}
// this delegate is called when the reversegeocoder fails to find a placemark
- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFailWithError:(NSError *)error
{
//invalid place
}
You can read up the documentation on Maps Annonations.
Here is the link
You can get location coordinates from any point in the MapView using the convertPoint:toCoordinateFromView: method of MapView
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).
I am a newbie in MapKit for iPhone and tried to implement this, for some reason I can't see the current location blue dot, anyone else had this issue????
#import "DetailMapViewController.h"
#import "mapAnnotations.h"
#implementation DetailMapViewController
#synthesize inStock;
-(void)getlocation:(CLLocationCoordinate2D)loc
{
location = loc;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationItem.title = #"Street View";
mapView = [[MKMapView alloc] initWithFrame:self.view.bounds];
mapView.delegate=self;
//MKCoordinateRegion region;
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(location, 5000, 5000);
mapAnnotations *ann = [[mapAnnotations alloc] init];
ann.title = #"";
ann.subtitle = #"";
ann.coordinate = region.center;
mapView.showsUserLocation = YES;
[mapView addAnnotation:ann];
[mapView setRegion:region animated:TRUE];
[mapView regionThatFits:region];
[self.view insertSubview:mapView atIndex:0];
}
- (MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>) annotation
{
MKPinAnnotationView *annView=[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"currentloc"];
if (annotation == mapView.userLocation)
{
annView = [mapView dequeueReusableAnnotationViewWithIdentifier:#"blueDot"];
if (annView != nil)
{
annView.annotation = annotation;
}
else
{
annView = [[[NSClassFromString(#"MKUserLocationView") alloc] initWithAnnotation:annotation reuseIdentifier:#"blueDot"] autorelease];
}
}
if([inStock isEqual:#"yes"]){
annView.pinColor = MKPinAnnotationColorGreen;
}
if([inStock isEqual:#"no"]){
annView.pinColor = MKPinAnnotationColorRed;
}
if([inStock isEqual:#"unknown"]){
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"greyPin.png"]];
[annView addSubview:imageView];
}
annView.animatesDrop=TRUE;
annView.canShowCallout = YES;
annView.calloutOffset = CGPointMake(-5, 5);
return annView;
}
- (void)dealloc {
[super dealloc];
}
#end
The way the viewForAnnotation is currently written, it should actually crash when trying to show the current location because the "blue dot" annotation view doesn't have the pinColor or animatesDrop properties.
Try changing it to the following:
- (MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>) annotation
{
if ([annotation isKindOfClass:MKUserLocation.class]) {
//user location view is being requested,
//return nil so it uses the default which is a blue dot...
return nil;
}
MKPinAnnotationView *annView=[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"currentloc"];
if([inStock isEqual:#"yes"]){
annView.pinColor = MKPinAnnotationColorGreen;
}
if([inStock isEqual:#"no"]){
annView.pinColor = MKPinAnnotationColorRed;
}
if([inStock isEqual:#"unknown"]){
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"greyPin.png"]];
[annView addSubview:imageView];
}
annView.animatesDrop=TRUE;
annView.canShowCallout = YES;
annView.calloutOffset = CGPointMake(-5, 5);
return annView;
}
On the simulator, the user's location will be Cupertino, CA, USA (a little south of San Francisco). If your own annotation is not within 5000 meters of that, you won't see the blue dot. You'll have to zoom out to see it.
self.mapView.showsUserLocation = YES;
i have got the Latitude and Longitude from XML Parsing how can i show MapAnnotation(pin) on the Map,Please help me....
Create a new class that implements the MKAnnotation protocol. This will hold the lat/long, and will also have a title and description which will be displayed if you select the annotation after it has been rendered on your map.
The controller for the view that will display the map will need to implement the - - (MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>) annotation; method of the MKMapViewDelegate protocol. The code in this method will look something like the code at the bottom (apologies for the poor formatting, I couldn't get right in here or at the bottom).
Then at some point in your controller code you will need to call something along the lines of [self.mapView addAnnotation: annotation]; where annotation is an instance of your custom annotation class created in step 1, with the lat/long set etc.
Finally, so that the viewForAnnotation method gets called correctly, and is something that is easy to miss, in interface builder, make sure that you set the delegate outlet of the MKMapView to be your controller (that implements the MKMapViewDelegate protocol.
-(MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>) annotation {
static NSString *AnnotationViewIdentifier = #"annotationViewIdentifier";
MKPinAnnotationView *annotationView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier: AnnotationViewIdentifier];
if (annotationView == nil) {
annotationView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier: AnnotationViewIdentifier] autorelease];
// This is all optional and depends on your requirements
annotationView.animatesDrop = NO;
annotationView.canShowCallout = YES;
annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
annotationView.enabled = YES;
annotationView.pinColor = MKPinAnnotationColorGreen;
}
return annotationView;
}
First you want to create MKAnnotation Protocol class (Here MyAnnotation class implements the MKAnnotation Protocol).This class should be includes lat, long, title, subtitle and also whatever you want.
Second, In your view controller, where you want to display the pin and you will implement this code,
AnnObj = [[MyAnnotation alloc] init];
AnnObj.latitude = [[latitude objectAtIndex:storyIndex] floatValue];
AnnObj.longitude = [[longitude objectAtIndex:storyIndex] floatValue];
MKCoordinateRegion region;
region.center = location;
MKCoordinateSpan span;
region.center.latitude = [[latitude objectAtIndex:storyIndex] floatValue];
region.center.longitude = [[longitude objectAtIndex:storyIndex] floatValue];
span.latitudeDelta = 0.0005;
span.longitudeDelta = 0.0005;
region.span = span;
[mapview setRegion:region animated:TRUE];
AnnObj.title = titleString;
AnnObj.subTitle = subTitleString;
NSString * titleString = [[buildingNames objectAtIndex:storyIndex] stringByReplacingOccurrencesOfString:#"\n\t" withString:#""];
[eventPoints addObject:AnnObj];
[mapview addAnnotations:eventPoints];
Third, Implement the MKAnnotation delegate method,
- (MKAnnotationView *)mapView: (MKMapView *)lmapView viewForAnnotation:(id <MKAnnotation>) annotation {
if (lmapView.userLocation == annotation){
return nil;
}
MKAnnotationView* myCusAnn = (MKAnnotationView*)[lmapView dequeueReusableAnnotationViewWithIdentifier:#"eventview"];
if(myCusAnn == nil)
{
myCusAnn = [[[ MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"eventview"] autorelease];
}
myCusAnn.canShowCallout = YES;
[myCusAnn setEnabled:YES];
return myCusAnn;
}
I hope it will help you.