The map screen of the app displays the user's current location. I want to allow the user to 'browse' the map (scroll around and explore other areas) and I have a button which returns the user to the point on the map with their current location BUT I'm what's happening is that the app isn't allowing the user to 'browse' the map and retain the view they are looking at, rather it jumps right back to the user's current location.
Here is some code:
-(void) setupLocation {
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
// locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.distanceFilter = kCLDistanceFilterNone; // whenever we move
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters; // 100 m
[locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
NSLog(#"didFailWithError: %#", error);
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
// [self.mapView setCenterCoordinate:self.mapView.userLocation.coordinate animated:YES];
tempLat = newLocation.coordinate.latitude;
tempLon = newLocation.coordinate.longitude;
CLLocationCoordinate2D currentLocation = CLLocationCoordinate2DMake(tempLat, tempLon);
MKCoordinateRegion viewRegionLocation = MKCoordinateRegionMakeWithDistance(currentLocation, 100, 100);
[self.mapView setRegion:viewRegionLocation animated:YES];
locationNew = [[CLLocation alloc] initWithLatitude:newLocation.coordinate.latitude longitude:newLocation.coordinate.longitude];
locationOld = [[CLLocation alloc] initWithLatitude:oldLocation.coordinate.latitude longitude:oldLocation.coordinate.longitude];
}
I also have:
- (IBAction)stopUpdating:(id)sender {
[locationManager stopUpdatingLocation];
}
And:
- (IBAction)findMe:(id)sender {
[locationManager startUpdatingLocation];
}
Any ideas of why the map keeps jumping back to the user's current location??
Thank you very much!
Because, in your - (void)locationManager: didUpdateToLocation: fromLocation: method you set the region of your mapview to the updated location everytime.
Removing this part will solve your problem.
MKCoordinateRegion viewRegionLocation = MKCoordinateRegionMakeWithDistance(currentLocation, 100, 100);
[self.mapView setRegion:viewRegionLocation animated:YES];
EDIT 1:
add this line in your viewDidLoad method,
self.mapView.showsUserLocation = YES;
change the find me button press method like this,
-(IBAction) findMeButtonPressed:(id)sender;{
MKCoordinateRegion viewRegionLocation = MKCoordinateRegionMakeWithDistance([self.locationManager location].coordinate, 100, 100);
[self.mapView setRegion:viewRegionLocation animated:YES];
}
Related
This seems like very basic question but I didnt find anything, and I have tried all!! I just want to make a button to zoom in into users location! This is what I've got so far:
CLLocationCoordinate2D userLocationCoordinate;
- (void)viewDidLoad {
[super viewDidLoad];
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide];
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0){
[self.locationmanager requestWhenInUseAuthorization];}
[locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
NSLog(#"OldLocation %f %f", oldLocation.coordinate.latitude, oldLocation.coordinate.longitude);
NSLog(#"NewLocation %f %f", newLocation.coordinate.latitude, newLocation.coordinate.longitude);
userLocationCoordinate.latitude = newLocation.coordinate.latitude;
userLocationCoordinate.longitude = newLocation.coordinate.longitude;
}
-(IBAction)showUserLocation:(id)sender{
[self.mapview setCenterCoordinate:userLocationCoordinate animated:YES];
}
Please I need help, If theres a way in which I dont use CLLocationManager it would be better.
Thanks.
You still need CLLocationManager to request location permission from the user,
but you can use the setUserTrackingMode method of MKMapView to ask the map view to centre on the user's location.
If you don't want to continue to update the map location as the user moves then you should set the tracking mode to Follow and then set it to None after a few seconds.
I am building an iOS application that display a POI in a MapView, but firstly I can display the map, and with iOS8 this is begin a problem.
I read a lot question in this site, but none run on my app even if the code seems right.
I entered into myapplicationTest-info.plist the following code
<key>NSLocationAlwaysUsageDescription</key>
And the code in the file.m is this:
#import "MapViewController.h"
#define IS_OS_8_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
#interface MapViewController ()
#end
#implementation MapViewController
#synthesize mapView = _mapView ;
- (void)viewDidLoad
{
[super viewDidLoad];
self.mapView.delegate = self;
self.locationManager.delegate = self;
self.locationManager = [[CLLocationManager alloc] init];
if (IS_OS_8_OR_LATER) {
//[self.locationManager requestWhenInUseAuthorization];
[self.locationManager requestAlwaysAuthorization];
}
[self.locationManager startUpdatingLocation];
self.mapView.showsUserLocation = YES;
[mapView setMapType:MKMapTypeStandard];
[mapView setZoomEnabled:YES];
[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;
[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.
}
#end
Where is the mistake?
Why it doesn't run?
You need to provide a value for NSLocationAlwaysUsageDescription key which is the string that describes why your app wants to use location services -
For example -
<key>NSLocationAlwaysUsageDescription</key>
<string>FindMeDonuts will use your location to identify nearby donut shops</string>
Also, rather than checking the iOS version, it is better to check if CLLocationManager responds to the authorisation selector -
if ([self.locationManager respondsToSelector:#selector(requestAlwaysAuthorization)]) {
[self.locationManager requestAlwaysAuthorization];
}
finally, this won't stop your map from updating, but it doesn't make sense - you are assigning a delegate to your CLLocationManager before you allocate and initialise it.
You should say -
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate=self;
I don't know if i understand your problem.
if your problem is about the map is not show, you need to set frame of your map.
self.mapView.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
hope i could help you
The best way is to use the -locationManager:didUpdateLocations method provided by CLLocationManagerDelegate.
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
[self.locationManager stopUpdatingLocation];
// Move this line here
self.mapView.showsUserLocation = YES;
}
After calling [self.locationManager startUpdatingLocation] in ViewDidLoad, you shouldn't set self.mapView.showsUserLocation to YES yet as permission to use location services is not yet approved. Use the delegate to wait/get a location update from the system before setting self.mapView.showsUserLocation to YES.
You also need to enable location services
if([CLLocationManager resolveClassMethod:#selector(locationServicesEnabled)]) {
[CLLocationManager locationServicesEnabled];
}
I have an app which displays the longitude and the latitude of the users position. The application asks for the current location, and the latitude and the longitude displays in Xcode. But in the app, nothing happens.
Here's my code:
- (NSString *)deviceLocation {
NSString *theLocation =
[NSString stringWithFormat:#"latitude: %f longitude: %f",
locationManager.location.coordinate.latitude,
locationManager.location.coordinate.longitude];
return theLocation;
}
In viewDidLoad:
locationManager = [[CLLocationManager alloc] init];
locationManager.distanceFilter = kCLDistanceFilterNone; // whenever we move
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters; // 100 m
[locationManager startUpdatingLocation];
NSLog(#"%#", [self deviceLocation]);
The problem is that the latitude and longitude -labels won't show the position.
My guess is that you're not assigning your view controller as a delegate to CLLocationManager.
You can do that via:
locationManager.delegate = self;
Right after you create your locationManager.
Then, you can update labels by having your view controller respond to the delegate method locationManager:didUpdateLocations:.
I'm trying to show a map in my application, it works on my simulator and on my ipod touch 4g.
But I always get an error on my iPhone and I don't know why this happens.
Maybe you can explain me why it fails.
The error is:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid Region <center:nan, nan span:nan, nan>'
I already searched for solutions on google and stackoverflow but it seems that nobody has this problem.
Thats my code:
//setup mapview
mapView.delegate = self;
mapView.showsUserLocation = YES;
//set up core location
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
//Set up zoom location
CLLocationCoordinate2D zoomLocation;
zoomLocation.latitude = locationManager.location.coordinate.latitude;
zoomLocation.longitude= locationManager.location.coordinate.longitude;
debug(#"Location: %f und %f",locationManager.location.coordinate.latitude,locationManager.location.coordinate.longitude);
//zoom to location
MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(zoomLocation, 0.5*METERS_PER_MILE, 0.5*METERS_PER_MILE);
MKCoordinateRegion adjustedRegion = [mapView regionThatFits:viewRegion];
[mapView setRegion:adjustedRegion animated:YES];
As I said, it works on iPod and simulator, but not on iPhone.
Hope you can help me
SOLUTION:
I used the locationManager too early, so the app crashed. Now I used it this way:
- (void)viewDidLoad {
[super viewDidLoad];
//setup mapview
mapView.delegate = self;
mapView.showsUserLocation = YES;
//set up core location
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
[locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{
//Set up zoom location
CLLocationCoordinate2D zoomLocation;
zoomLocation.latitude = newLocation.coordinate.latitude;
zoomLocation.longitude= newLocation.coordinate.longitude;
MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(zoomLocation, 0.5*METERS_PER_MILE, 0.5*METERS_PER_MILE);
MKCoordinateRegion adjustedRegion = [mapView regionThatFits:viewRegion];
[mapView setRegion:adjustedRegion animated:YES];
debug(#"Location: %f und %f",newLocation.coordinate.latitude,newLocation.coordinate.longitude);
}
Don't know if this way is 100% correct, but it works.
Ok, here's my attempt at using CLLoactionManager
- (void)viewDidLoad {
[super viewDidLoad];
mapView=[[MKMapView alloc] initWithFrame:self.view.frame];
//mapView.showsUserLocation=TRUE;
mapView.delegate=self;
[self.view insertSubview:mapView atIndex:0];
CLLocationManager *locationManager=[[CLLocationManager alloc] init];
locationManager.delegate=self;
locationManager.desiredAccuracy=kCLLocationAccuracyNearestTenMeters;
[locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
mStoreLocationButton.hidden=FALSE;
location=newLocation.coordinate;
//One location is obtained.. just zoom to that location
MKCoordinateRegion region;
region.center=location;
MKCoordinateSpan span;
span.latitudeDelta=0.01;
span.longitudeDelta=0.01;
region.span=span;
[mapView setRegion:region animated:TRUE];
}
My problem is that [locationManager startUpdatingLocation]; doesn't seem to fire the next method. What am I missing? I've tried setting breakpoints in the second method, but they never catch. Obviously it's not being used.
You should look into using a CLLocationManager to get the current location to feed your MKMapView with the correct coordinates.
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
MKMapView *map = [[MKMapView alloc] init];
[locationManager startUpdatingLocation];
CLLocationCoordinate2D _coordinate = locationManager.location.coordinate;
MKCoordinateRegion extentsRegion = MKCoordinateRegionMakeWithDistance(_coordinate, 800, 800);
[map setRegion:extentsRegion animated:YES];
This looks like a good place to start. In order to drop a pin, you need to know the coordinates. Using - (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation will help you get the user's location so that you can create an MKAnnotation and MKPinAnnotationViews. Its pretty straight forward once you get started.