How to follow user location with MapKit
Solution 1
I think that I would actually use the CoreLocation CLLocationManager
and use its delegate method locationManager:didUpdateToLocation:fromLocation:
.
This way, you don't have the overhead of an NSTimer
, and it only updates when there's a new location available.
You can pull the longitude and latitude from the CLLocation
object sent to the locationManager:didUpdateToLocation:fromLocation:
method and pass it to the map view.
Solution 2
If you're on IOS5+ this is VERY easy. Just change the "userTrackingMode" using code such as:
[_mapView setUserTrackingMode:MKUserTrackingModeFollow animated:YES];
This will smoothly follow the users current location. If you drag the map it will even set the tracking mode back to MKUserTrackingModeNone
which is usually the behaviour you want.
Solution 3
It's really simple to have the map update the user location automatically just like the google maps. Simply set showsUserLocation to YES
self.mapView.showsUserLocation = YES
...and then implement the MKMapViewDelegate to re-center the map when the location is updated.
-(void) mapView:(MKMapView *)mapView
didUpdateUserLocation:(MKUserLocation *)userLocation
{
if( isTracking )
{
pendingRegionChange = YES;
[self.mapView setCenterCoordinate: userLocation.location.coordinate
animated: YES];
}
}
And to allow the user to zoom & pan without stealing the view back to the current location...
-(void) mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated
{
if( isTracking && ! pendingRegionChange )
{
isTracking = NO;
[trackingButton setImage: [UIImage imageNamed: @"Location.png"]
forState: UIControlStateNormal];
}
pendingRegionChange = NO;
}
-(IBAction) trackingPressed
{
pendingRegionChange = YES;
isTracking = YES;
[mapView setCenterCoordinate: mapView.userLocation.coordinate
animated: YES];
[trackingButton setImage: [UIImage imageNamed: @"Location-Tracking.png"]
forState: UIControlStateNormal];
}
Carl Boisvert
Updated on April 21, 2020Comments
-
Carl Boisvert about 4 years
I'm using MapKit to display the user's location relative to pins around them. I'd like to be able to mimic the functionality that Maps provides via the crosshair button in the lower left-hand corner of the screen. I'm already aware that MapKit provides a CLLocation object with the user's location via MKUserLocation, I just wanted to seek advice on how I should keep focus on that location. My initial inclination was to use an NSTimer to center the map on that coordinate every 500ms or so.
Is there a better way to do this? Is there something built in to MapKit that I'm missing that will accomplish this?
Thanks so much, Brendan
-
Carl Boisvert about 14 yearsWouldn't this be more inneficient in the end though since MapKit is already using the GPS anyway? I would think that GPS would use more power than a timer. That being said there's a really good chance I'm wrong. I've only been programming on the iphone for 1 week.
-
Jacob Relkin about 14 yearsSo you're saying the Core Location doesn't use GPS?
-
Carl Boisvert about 14 yearsI'm saying CL does use GPS. So if two classes were pinging the GPS receiver (MapKit's internal CLLocationManager for the blue user location pin and your proposed CLLocationManager) it could wind up using a lot more power than the one internal MapKit CLLocationManager and a simple NSTimer. I suppose this comes down to whether the iPhone SDK is smart enough to support multiple CLLocationManagers without attaching each one to the GPS directly. Or perhaps the MapKit delegate provides it's own didUpdateToLocation:?
-
Carl Boisvert about 14 yearsI guess I'll just have to trust that this isn't going to destroy battery life :)
-
quantumpotato over 13 yearsIs it better to use the MKMApView's center with following user location than CoreLocation? I did have a LocationUpdater class which returns a new CLLocation when it updates. Does MKMapView update with the same frequency?
-
KPM over 9 yearsAnother proof of the obvious limitations of the concept of accepted answer. This is the answer that should be on top! Jacob's answer was great four years ago but now completely obsolete, yet it will stay forever displayed as the first answer.