Tracking the user
One of the most useful features of MKMapView is
setUserTrackingMode:(MKUserTrackingMode). It is a very easy way to trigger
zooming to and following the user's vicinity:
[self.mapView setUserTrackingMode:MKUserTrackingModeFollow animated:YES];
This results in the map displaying a blue dot where the user is at and the map pans to follow the dot as the user moves through the world:

ArcGIS SDK for iOS includes a similarly easy functionality through the AGSGPS
class, available via the gps property of AGSMapView objects. It also gives
the developer flexibility by being able to set both "auto-panning" and "wander
extent" properties. Auto-panning is to set if the map should pan to follow the
user dot or not; wander extent is a float between 0 and 1 to set a threshold
to being auto-panning at. It is calculated as a percent of the visible area.
self.mapView.autoPanMode = AGSGPSAutoPanModeDefault;
self.mapView.wanderExtentFactor = 0.25;
[self.mapView.gps start];

NOTE: you may notice that the extent of the ArcGIS Map is much smaller than
the MapKit map. Currently, this is unsettable when using the convenience
method AGSGPS#start. As noted on the ArcGIS resources site,
AGSGPS "provides a simple façade over the CoreLocation framework and greatly
simplifies working with location services." However, you can implement
auto-panning on your own...
Handrolling Autopanning
If the zoom level that AGSGPS#start uses is a bit too close for you, it is
simple enough to implement your own auto-panning feature:
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
CLLocation *location = [locations objectAtIndex:(locations.count - 1)];
CLLocationCoordinate2D latlng = location.coordinate;
float extentDelta = 0.01;
AGSEnvelope *envelope = [AGSEnvelope envelopeWithXmin:(latlng.longitude - extentDelta)
ymin:(latlng.latitude - extentDelta)
xmax:(latlng.longitude + extentDelta)
ymax:(latlng.latitude + extentDelta)
spatialReference:[AGSSpatialReference wgs84SpatialReference]];
[self.mapView zoomToEnvelope:envelope animated:YES];
}
Handling User Pan and Zoom
Apple provides a lot of helpful delegate methods in the MKMapKitDelegate
protocol. Two of these are:
– mapView:regionWillChangeAnimated:– mapView:regionDidChangeAnimated:
Implementing these delegate methods allows you to respond to common events such as the user panning around or zooming in or out. This is very simple in MapKit:
- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated
{
NSLog(@"started panning or zooming");
}
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
{
NSLog(@"stopped panning or zooming");
}
The same thing can be done using Key-Value Observation with ArcGIS SDK for iOS.
To acheive the same result as handling regionWillChangeAnimated, the value of
the AGSMapView object that you want to observe is keyed at visibleArea. For
regionDidChangeAnimated, you want to listen for two NSNotifications:
- MapDidEndPanning
- MapDidEndZooming
Here is some example code for this scenario:
// key to watch on the AGSMapView object
static NSString *const LQRegionWillChangeObserverKeyPath = @"self.mapView.visibleArea";
- (void)viewDidLoad
{
[super viewDidLoad];
[self addObserver:self forKeyPath:LQRegionWillChangeObserverKeyPath options:NSKeyValueObservingOptionNew context:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mimicRegionDidChange) name:@"MapDidEndPanning" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mimicRegionDidChange) name:@"MapDidEndZooming" object:nil];
}
- (void)dealloc {
[self removeObserver:self forKeyPath:LQRegionWillChangeObserverKeyPath];
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if ([keyPath isEqualToString:LQRegionWillChangeObserverKeyPath]) {
[self mimicRegionWillChange];
}
}