In my app, I am using GMSMapView, and I would like to change tracking mode. In iOS MapKit, I can change the tracking mode to MKUserTrackingModeFollowWithHeading, but don't know how to change it in GMSMapView.
In the app Google Maps, it is working after second touch on myLocationButton. Is it possible?
For continuously changing the camera with the current location, you will need to update the GMSCamera for google maps to current location. You can do it in Location Manager delegate method.
CLLocation *location;
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
//Get current latitude and longitude from didUpdateLocation
location = [locations lastObject];
}
-(void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading
{
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:location.coordinate.latitude longitude:location.coordinate.longitude zoom:10 bearing:newHeading.trueHeading viewingAngle:0];
//You can change viewingAngle from 0 to 45
[self.mapForView animateToCameraPosition:camera];
}
In case your delegate is not getting called, take help from my answer here
Hope it helps.
Related
I have created a sample application for tracking GPS locations based on geofencing. First of all I have created one geofence and added the same to monitoring, using same location placed a circular overlay on MapView.
CLLocationCoordinate2D centerCoordinate1 = CLLocationCoordinate2DMake(23.518192, 72.337122);
CLCircularRegion *region1 =[[CLCircularRegion alloc] initWithCenter:centerCoordinate1 radius:100 identifier:#"Location First"];
NSLog(#"%#",[region1 description]);
region1.notifyOnEntry=YES;
region1.notifyOnExit=YES;
[self.locationManager startMonitoringForRegion:region1];
NSLog(#"Started Monitoring- %#", [region1 description]);
[self.mapview setShowsUserLocation:YES];
[self.mapview setUserTrackingMode:MKUserTrackingModeFollow animated:YES];
// create circle around monitor region and check if worker location is changed
MKCircle *circle1 = [MKCircle circleWithCenterCoordinate:centerCoordinate1 radius:100];
[self.mapview addOverlay:circle1];
Now, I am testing different co-ordinates in simulator by changing the simulator location by Debug->Location->Custom Locations.
If I am change major lat-long then it will call the region enter/exit methods, but if I am checking with near by locations by +/- with 10 or 20 points in latitude and longitude repetatively.
First Image which is inside the GeoFence
Another Image which is outside the GeoFence
Another image is visually outside the GeoFence, but while setting up this latitude and longitude it does not call region exit method.
Below are the region monitoring methods
-(void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region;
-(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region;
-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region;
I am adding 4 to 5 regions to monitor at the same time.
Any help would be highly appreciated.
Not sure why this happens but when it does we'd prefer not to show the user that their current location is 0,0 (it's in the middle of the ocean off the coast of South Africa). Is there any way to detect when this happens so we can show an error message or something to the user?
Looks like you are not authorized to access the current location of the device. For that, you'll have to add these two keys into your plist:
NSLocationAlwaysUsageDescription
NSLocationWhenInUseUsageDescription
Now when you're done with with it, you will have to request for authorization like this :
if ([locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)])
{
[locationManager requestWhenInUseAuthorization];
}
So now when you are done with authorization, you need to start getting location updates. For this, use this line :
[locationManager startUpdatingLocation];
Now if you wish to go to the current location, you need to implement this method here:
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
CLLocation *location = [locations lastObject];
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:location.coordinate.latitude longitude:location.coordinate.longitude zoom:currentZoom];
[self.gMapView animateToCameraPosition:camera];
}
This will keep updating the map with current location.
If you just want to current location once, just put a conditional statement for the same.
If user denies the permission, following method will be called :
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{
if([CLLocationManager locationServicesEnabled])
{
if([CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied)
{
// Put your alert here.
}
}
}
I am new in location services. I have used startMonitoringSignificantLocationChanges and (void)locationManager:(CLLocationManager *)manager didUpdateToLocation: (CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation method but it is not getting called as I change location value. I want to fetch location value whenever user change its location.How should i achieve this? Please help me to resolve. Thanks in advance.
You need to implement "didUpdateLocations" delegate method . Here is sample
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
NSLog(#"locations : %#",locations.description);
CLLocation *currentLocation = [locations lastObject];
NSLog(#"current location : %f %f",currentLocation.coordinate.latitude,currentLocation.coordinate.longitude);
}
In iOS 8 you need to do two extra things to get location working:
1. add one or both of the following keys to your Info.plist file:
NSLocationWhenInUseUsageDescription
NSLocationAlwaysUsageDescription
Next you need to request authorization for the corresponding location method, WhenInUse or Background. Use one of these calls:
[self.locationManager requestWhenInUseAuthorization];
[self.locationManager requestAlwaysAuthorization];
For details refer following link. http://nevan.net/2014/09/core-location-manager-changes-in-ios-8/
I init my mapviewControler like this:
- (void)viewDidLoad
{
[super viewDidLoad];
self.firstShow=TRUE;
self.mapView.delegate=self;
self.mapView.showsUserLocation=YES;
self.cllmng=[[CLLocationManager alloc]init];
self.cllmng.delegate=self;
self.cllmng.desiredAccuracy=kCLLocationAccuracyNearestTenMeters;
self.cllmng.distanceFilter=50;
[self.cllmng startUpdatingLocation];
}
and I make mapviewControler implement CLLocationManagerDelegate, and implement - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations in my code.
The problem I have is that I want to init map view centred on current user location with a proper scale. I intend to do this by
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
CLLocation * currentLoci=[locations lastObject];
MKCoordinateRegion r;
MKCoordinateSpan span;
span.latitudeDelta = 1;
span.longitudeDelta = 1;
r.span = span;
CLLocationCoordinate2D c;
c.longitude=currentLoci.coordinate.longitude;
c.latitude=currentLoci.coordinate.latitude;
r.center = c;
[self.mapView setRegion:r animated:YES];
}
But sometimes, after [self.cllmng startUpdatingLocation] called in the -(void) viewDidload, I cannot get a call of - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations immediately. Thus, the map view just init showing user location but showing the whole Australia. How can I set the scale/span in the init of map view even didUpdateLocations is not triggered? THX!
INstead of modifying the region yourself using a CLLocation manager you could just set the trackingMode of the mapView and it'll center and zoom in on your position automatically. It will be possible for the user to disable the tracking mode if they start dragging the map around, but you can disable user interaction if you really want them to have no control. Here is how to do it
[self.mapView setUserTrackingMode:MKUserTrackingModeFollow animated:YES];
ref: https://developer.apple.com/library/ios/documentation/MapKit/Reference/MKMapView_Class/MKMapView/MKMapView.html#//apple_ref/occ/instm/MKMapView/setUserTrackingMode:animated:
iOS 11.x Swift 4.0 Craigs answer, updated.
mapView.showsUserLocation = true
Not so obvious I fear.
I have an application that needs to detect the users location an drop some MKAnnotations around it on the MKMapView. How can I get notified about wether the user has selected YES on the Location Services prompt in order to then call my method to get the users location and add the annotations?
This will happen in the location manager delegate didUpdateToLocation;
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
MyAnnotation * annotation = [[MyAnnotation alloc] initWithCoordinate:coordinate];
[self.mapView addAnnotation:annotation];
}
You will need to create a MyAnnotation class. Take a look here: https://stackoverflow.com/a/2878806/1535038