I have used map in my view controller but when the maps loads it shows me view of the whole country. I want to show my current location view when maps loads, for that I have used didUpdateUserLocation method and set delegate for it.
My code is this:
-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation{
[self.mapView setRegion:MKCoordinateRegionMake(_userLocation.coordinate, MKCoordinateSpanMake(0.1f, 0.1f)) animated:YES];
}
Now when my map loads it animate and zoom but in wrong location. It is taking me to any location in sea when map loads , but my current location is different.
I have also tested it in real device but it does not show my location.
The maps looks like that when loads:
ViewController class code:
#property BOOL updateUserLocation;
#property(strong,nonatomic) CLLocation *userLocation;
#property (nonatomic, retain) MKPolyline *routeLine;
#property (nonatomic, retain) MKPolylineView *routeLineView;
#property (nonatomic,retain) NSString *latitude;
#property (nonatomic,retain) NSString *longitude;
- (void)viewDidLoad {
[super viewDidLoad];
[[self navigationController] setNavigationBarHidden:YES animated:YES];
_AlertView.hidden=YES;
_distanceView.hidden=YES;
self.mapView.zoomEnabled=YES;
locationManager = [[CLLocationManager alloc]init];
locationManager.delegate = self;
[locationManager startUpdatingLocation];
[self.mapView setShowsUserLocation:YES];
[self.mapView setDelegate:self];
}
-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation{
[self.mapView setRegion:MKCoordinateRegionMake(_userLocation.coordinate, MKCoordinateSpanMake(0.1f, 0.1f)) animated:YES];
}
Add these lines in the viewDidLoad:
self.mapView.showsUserLocation = YES;
if you want to center the map to the user location add this:
[self.mapView setCenterCoordinate:mapView.userLocation.location.coordinate animated:YES];
EDIT:
ViewController example:
#import "ViewController.h"
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>
#interface ViewController () <CLLocationManagerDelegate>
#property (weak, nonatomic) IBOutlet MKMapView *mapView;
#property (nonatomic, strong) CLLocationManager *locationManager;
#property (nonatomic, strong) CLLocation *location;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[[self mapView] setShowsUserLocation:YES];
self.locationManager = [[CLLocationManager alloc] init];
// we have to setup the location manager with permission in later iOS versions
if ([[self locationManager] respondsToSelector:#selector(requestWhenInUseAuthorization)]) {
[[self locationManager] requestWhenInUseAuthorization];
}
[[self locationManager] setDelegate:self];
[[self locationManager] setDesiredAccuracy:kCLLocationAccuracyBest];
[[self locationManager] startUpdatingLocation];
}
-(void) locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
// Stop updating location, when you want to restart update use [[self locationManager] startUpdatingLocation];
[manager stopUpdatingLocation];
self.location = locations.lastObject;
// zoom the map into the users current location
MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance
(self.location.coordinate, 2, 2);
[[self mapView] setRegion:viewRegion animated:YES];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
I've only added the IBOutlet on the storyboard and the NSLocationWhenInUseUsageDescription key in the plist.
If you change the location on the simulator you can see the maps change location.
If you want I can upload the complete example project.
NEW EDIT:
There is an error in you code!
When you use [self.mapView setRegion:MKCoordinateRegionMake(_userLocation.coordinate, MKCoordinateSpanMake(0.1f, 0.1f)) animated:YES], you use _userLocation that is your CLLocation variable! You must use userLocation that is the value that you receive from the method.
I recommend you to change the CCLocation variable name and use the userLocation name only for the variable used in the didUpdateUserLocation method.
You can call this method and zoom on map
CLLocationCoordinate2D zoomLocation;
zoomLocation.latitude = ; // your latitude value
zoomLocation.longitude= // your longitude value
MKCoordinateRegion region;
MKCoordinateSpan span;
span.latitudeDelta=0.18; // change as per your zoom level
span.longitudeDelta=0.18;
region.span=span;
region.center= zoomLocation;
[mapview setRegion:region animated:TRUE];
[mapview regionThatFits:region];
Use didUpdateToLocation instead of didUpdateUserLocation.
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
[self.locationManager stopUpdatingLocation];
MKCoordinateRegion region;
region.span.latitudeDelta = 0.005;
region.span.longitudeDelta = 0.005;
region.center.latitude = newLocation.coordinate.latitude;
region.center.longitude = newLocation.coordinate.longitude;
[self.mapView setRegion:region animated:YES];
}
See also my library.
https://github.com/koogawa/KGWLocationPicker/blob/master/KGWLocationPicker/KGWLocationPickerViewController.m
Related
i got this error what that error meant to be.i can't understand what error it is.
so plz help
thanks
error
1.ViewController.h
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>
#interface ViewController : UIViewController<MKMapViewDelegate>
#property (weak, nonatomic) IBOutlet MKMapView *mycurrentlocation;
#end
2. ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController #synthesize mycurrentlocation;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.mycurrentlocation.delegate = self; }
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated. }
-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation {
MKCoordinateRegion re = MKCoordinateRegionMakeWithDistance(userLocation.coordinate, 800,
800);
[self.mycurrentlocation setRegion:[self.mycurrentlocation regionThatFits:re] animated:YES];
MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
point.coordinate = userLocation.coordinate;
point.title = #"Where am I?";
point.subtitle = #"I'm here!!!";
[self.mycurrentlocation addAnnotation:point]; }
#end
Then put this line of code in the viewDidLoad method of your class:
[self.locationManager requestAlwaysAuthorization];
You need to add the core location framework and Map Kit framework.
In your AppName-Info.plist Add a new row with the key name being:
NSLocationWhenInUseUsageDescription
Or
NSLocationAlwaysUsageDescription
With the value being a string of the message that you want to be displayed:
YourAppName would like to use your location.
In your header file. (I use App Name-Prefix.pch but YourViewController.h will work too)
#define IS_OS_8_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
YourViewController.h
#import <MapKit/MapKit.h>
#import <MapKit/MKAnnotation.h>
#interface YourViewController : UIViewController <MKMapViewDelegate, CLLocationManagerDelegate> {
}
#property(nonatomic, retain) IBOutlet MKMapView *mapView;
#property(nonatomic, retain) CLLocationManager *locationManager;
YourViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
mapView.delegate = self;
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
#ifdef __IPHONE_8_0
if(IS_OS_8_OR_LATER) {
// Use one or the other, not both. Depending on what you put in info.plist
[self.locationManager requestWhenInUseAuthorization];
[self.locationManager requestAlwaysAuthorization];
}
#endif
[self.locationManager startUpdatingLocation];
mapView.showsUserLocation = YES;
[mapView setMapType:MKMapTypeStandard];
[mapView setZoomEnabled:YES];
[mapView setScrollEnabled:YES];
}
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:YES];
self.locationManager.distanceFilter = kCLDistanceFilterNone;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[self.locationManager startUpdatingLocation];
NSLog(#"%#", [self deviceLocation]);
//View Area
MKCoordinateRegion region = { { 0.0, 0.0 }, { 0.0, 0.0 } };
region.center.latitude = self.locationManager.location.coordinate.latitude;
region.center.longitude = self.locationManager.location.coordinate.longitude;
region.span.longitudeDelta = 0.005f;
region.span.longitudeDelta = 0.005f;
[mapView setRegion:region animated:YES];
}
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(userLocation.coordinate, 800, 800);
[self.mapView setRegion:[self.mapView regionThatFits:region] animated:YES];
}
- (NSString *)deviceLocation {
return [NSString stringWithFormat:#"latitude: %f longitude: %f", self.locationManager.location.coordinate.latitude, self.locationManager.location.coordinate.longitude];
}
- (NSString *)deviceLat {
return [NSString stringWithFormat:#"%f", self.locationManager.location.coordinate.latitude];
}
- (NSString *)deviceLon {
return [NSString stringWithFormat:#"%f", self.locationManager.location.coordinate.longitude];
}
- (NSString *)deviceAlt {
return [NSString stringWithFormat:#"%f", self.locationManager.location.altitude];
}
I'd like to have a map with just two points, the users location and a single annotation (it's for a pov). I have included what I
have below. Ideally, I would like it to handle if the user is 100 feet away or 100 miles in displaying both the User and the annotation in
the map view. I think it would be best if the location were at the center and the user were on the edge with some reasonable 20% buffer on the edge of the map view. I only need to support iOS 7 and greater.
Is there something like sizeToFit for annotations that takes into account users position as an annotation?
my MapViewController.h
#interface MapViewController : UIViewController <MKMapViewDelegate, CLLocationManagerDelegate>
#property (weak, nonatomic) IBOutlet MKMapView *mapView;
#property (strong, nonatomic) CLLocationManager *locationManager;
#end
my MapViewController.m:
#define IS_OS_8_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
#import "MapViewController.h"
#import "MYUtility.h"
#interface MapViewController (){
NSMutableArray *_yourAnnotationArray;
MKPointAnnotation *_locationPoint;
BOOL _firstTime;
}
#end
#implementation MapViewController
- (void)viewDidLoad {
[super viewDidLoad];
_firstTime=YES;
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
if(IS_OS_8_OR_LATER) {
//[self.locationManager requestWhenInUseAuthorization];
//[self.locationManager requestAlwaysAuthorization];
[self.locationManager requestWhenInUseAuthorization];
[self.locationManager startUpdatingLocation];
}
[self.locationManager startUpdatingLocation];
[self.mapView setShowsUserLocation:YES];
[self.mapView setUserTrackingMode:MKUserTrackingModeFollow animated:YES];
CGFloat latitude=MYLocationLatitude();
CGFloat longitude=MYLocationLongitude();
_locationPoint = [[MKPointAnnotation alloc] init];
_locationPoint.coordinate = CLLocationCoordinate2DMake(latitude, longitude);
_locationPoint.title = #"Where am I?";
_locationPoint.subtitle = #"I'm here!!!";
[self.mapView addAnnotation:_locationPoint];
}
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
//if(_firstTime){
NSLog(#"here is my thinking %#", [locations lastObject]);
[self setMapStart];
}
-(void)setMapStart
{
//if(_firstTime){
NSLog(#"at top of _firstTime being true");
MKPointAnnotation *myPoint = [[MKPointAnnotation alloc] init];
myPoint.coordinate = CLLocationCoordinate2DMake(34.035645, -118.233434);
MKMapPoint annotationPoint = MKMapPointForCoordinate(self.mapView.userLocation.coordinate);
//[_yourAnnotationArray addObject:annotationPoint];
_yourAnnotationArray=[[NSMutableArray alloc] initWithObjects:_locationPoint,annotationPoint, nil];
//NSLog(#"here is my count: %i",(unsigned long)[_yourAnnotationArray count]);
[self.mapView showAnnotations:self.mapView.annotations animated:YES]; // <- determine when this has run
_firstTime=NO;
//}
}
Getting the user location to work has been killing me...
I've read lots of threads explaining the new changes with iOS 8 and how there must be one of two keys (NSLocationWhenInUseUsageDescription or NSLocationAlwaysUsageDescription) in the info.plist file in order for the app to ask permission to get user location. I did that.
I've also included what I believe as all the code needed for the location service to work...but it doesn't. Please see my mapViewController.h and mapViewController.m files below:
mapViewController.h
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import <MapKit/MKAnnotation.h>
#define IS_OS_8_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
#interface mapViewController : UIViewController <MKMapViewDelegate, CLLocationManagerDelegate>
#property(nonatomic, retain) IBOutlet MKMapView *mapView;
#property(nonatomic, retain) CLLocationManager *locationManager;
#end
mapViewController.m
#import "mapViewController.h"
#interface mapViewController ()
#end
#implementation mapViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.mapView.delegate = self;
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
#ifdef __IPHONE_8_0
if(IS_OS_8_OR_LATER) {
// Use one or the other, not both. Depending on what you put in info.plist
//[self.locationManager requestWhenInUseAuthorization];
[self.locationManager requestAlwaysAuthorization];
}
#endif
[self.locationManager startUpdatingLocation];
self.mapView.showsUserLocation = YES;
[self.mapView setMapType:MKMapTypeStandard];
[self.mapView setZoomEnabled:YES];
[self.mapView setScrollEnabled:YES];
}
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:YES];
self.locationManager.distanceFilter = kCLDistanceFilterNone; //Whenever we move
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[self.locationManager startUpdatingLocation];
NSLog(#"%#", [self deviceLocation]);
//View Area
MKCoordinateRegion region = { { 0.0, 0.0 }, { 0.0, 0.0 } };
region.center.latitude = self.locationManager.location.coordinate.latitude;
region.center.longitude = self.locationManager.location.coordinate.longitude;
region.span.longitudeDelta = 0.005f;
region.span.longitudeDelta = 0.005f;
[self.mapView setRegion:region animated:YES];
}
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(userLocation.coordinate, 800, 800);
[self.mapView setRegion:[self.mapView regionThatFits:region] animated:YES];
}
- (NSString *)deviceLocation {
return [NSString stringWithFormat:#"latitude: %f longitude: %f", self.locationManager.location.coordinate.latitude, self.locationManager.location.coordinate.longitude];
}
- (NSString *)deviceLat {
return [NSString stringWithFormat:#"%f", self.locationManager.location.coordinate.latitude];
}
- (NSString *)deviceLon {
return [NSString stringWithFormat:#"%f", self.locationManager.location.coordinate.longitude];
}
- (NSString *)deviceAlt {
return [NSString stringWithFormat:#"%f", self.locationManager.location.altitude];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
#end
Also, in case this is relevant, the mapViewController is tied to a tab in a Tab View Controller. When I click on the tab that includes the view controller containing MKMapView, I get the below image:
Use this code and run the application in device to get the current location.
If you run in simulator, then it will show the default location i.e Apple Inc's address as current location.
- (void)viewDidLoad
{
[super viewDidLoad];
self.locationManager = [[CLLocationManager alloc] init];
[self.locationManager setDelegate:self ];
self.mapView.showsUserLocation=YES;
[self.locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation: (CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
[self.mapView setCenterCoordinate:newLocation.coordinate animated:YES];
MKCoordinateRegion region=MKCoordinateRegionMakeWithDistance(newLocation.coordinate,70000 ,70000 );
MKCoordinateRegion adjustedRegion = [self.mapView regionThatFits:region];
[self.mapView setRegion:adjustedRegion animated:YES];
}
Note:
Turn on data or wifi in your device, or else you will face Location Accuracy error.
Add the below code to your ViewController.h class,
#interface ViewController : UIViewController<CLLocationManagerDelegate>
#property(nonatomic, retain) CLLocationManager *locationManager;
#end
And in ViewController.m class ,
-(void)viewWillAppear:(BOOL)animated{
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.locationManager.distanceFilter = kCLDistanceFilterNone;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[self.locationManager startUpdatingLocation];
[super viewWillAppear:animated];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
CLLocationCoordinate2D zoomLocation = CLLocationCoordinate2DMake(newLocation.coordinate.latitude, newLocation.coordinate.longitude);
}
Per the docs, [self.locationManager requestAlwaysAuthorization] is asynchronous. Implement the location services auth changed delegate callback and start monitoring there only after the auth status is allowed.
I can't understand how CLLocationManager get my current location coordinates ? if I don't call [locationManager startUpdatingLocation] and don't set parameters in locationManager.location.coordinate.
ViewController.h
#interface ViewController : UIViewController <MKMapViewDelegate, CLLocationManagerDelegate>
{
CLLocationManager *locationManager;
}
#property (weak, nonatomic) IBOutlet MKMapView* mapView;
#end
ViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
self.mapView.delegate = self;
[self.mapView setShowsUserLocation:YES];
locationManager = [[CLLocationManager alloc] init];
[locationManager setDelegate:self];
[locationManager setDistanceFilter:kCLDistanceFilterNone];
[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
}
-(void) mapView:(MKMapView *) mv didAddAnnotationViews:(NSArray *)views {
MKCoordinateRegion region;
region = MKCoordinateRegionMakeWithDistance(locationManager.location.coordinate, 1000, 1000);
[mv setRegion:region animated:YES];
}
Most likely it's a cached value after MapView requested current location update because of the following line:
[self.mapView setShowsUserLocation:YES];
I have the users location on my app, but how would I drop an annotation on the current user location? Would I have to get the long & lat of the users location and drop an annotation that way? or how would I do it?
First import the necessary frameworks (CoreLocation and MapKit).
Then create the Objective-C NSObject class Annotation
Setup its .h:
#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
#import <MapKit/MapKit.h>
#interface Annotation : NSObject <MKAnnotation>
#property (nonatomic) CLLocationCoordinate2D coordinate;
#property (nonatomic, copy) NSString *title;
#property (nonatomic, copy) NSString *subtitle;
#end
Setup its .m:
#import "Annotation.h"
#implementation Annotation
#synthesize coordinate, title, subtitle;
#end
Setup viewDidLoad
if ([CLLocationManager locationServicesEnabled]) {
locationManager = [[CLLocationManager alloc] init];
[locationManager setDelegate:self];
[locationManager setDesiredAccuracy: kCLLocationAccuracyBestForNavigation];
[locationManager startUpdatingLocation];
}
self.mapView.delegate = self;
Setup the didUpdateToLocation
// IMPORT ANNOTATION
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
[locationManager stopUpdatingLocation];
double miles = 3.10686;
double scalingFactor = ABS((cos(2 * M_PI * newLocation.coordinate.latitude / 360.0)));
MKCoordinateSpan span;
span.latitudeDelta = miles/69.0;
span.longitudeDelta = miles/(scalingFactor * 69.0);
MKCoordinateRegion region;
region.span = span;
region.center = newLocation.coordinate;
[self.mapView setRegion:region animated:YES];
Annotation *annot = [[Annotation alloc] init];
annot.coordinate = newLocation.coordinate;
[self.mapView addAnnotation:annot];
}
The simplest way is to set showsUserLocation to YES on your MKMapView and implement
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation {
MKCoordinateRegion region = MKCoordinateRegionMake(userLocation.location.coordinate, MKCoordinateSpanMake(0.01, 0.01));
[mapView setRegion:region animated:NO];
}
in your MKMapViewDelegate to have the map view move to that location when the user's location has been found.
This will show a blue dot on the map view at the user's location like the Maps app does.