Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MKMapView doesn't zoom correctly while user tracking mode is MKUserTrackingModeFollowWithHeading

I created a test project with few lines of code and with two components: MKMapView and UIButton. I ticked mapView option - Shows user location. Also I defined an action for the button, it zooms the map to user location.

Here is code from controller:

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];

    self.mapView.userTrackingMode = MKUserTrackingModeFollowWithHeading;
    self.mapView.delegate = self;
}

- (IBAction)changeRegion:(id)sender {
    MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(self.mapView.userLocation.coordinate, 200.0f, 200.0f);
    [self.mapView setRegion:region animated:YES];
}

Pretty simple and straightforward, isn't it? But when I tap the button I see weird behaviour: map view zooms to specified region then returns back to original zoom. What's the problem? How can I keep zooming and track user location at the same time?

I notice similar behaviour with MKUserTrackingModeFollow tracking mode.

P.S. I forgot to mention that it's a problem mostly for iOS7

like image 449
Ossir Avatar asked Oct 22 '13 12:10

Ossir


1 Answers

From apple documentation:

Setting the tracking mode to MKUserTrackingModeFollow or MKUserTrackingModeFollowWithHeading causes the map view to center the map on that location and begin tracking the user’s location. If the map is zoomed out, the map view automatically zooms in on the user’s location, effectively changing the current visible region.

If you want both to adjust the region and to track the user, I suggest you check for location updates and adjust zoom accordingly.

For example:

- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation {
    MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(userLocation.coordinate, 200.0f, 200.0f);
    [self.mapView setRegion:region animated:YES];
}

EDIT

Instead of setting the region, try just setting the center,

- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation {
    [self.mapView setCenterCoordinate:userLocation.location.coordinate animated:YES];
}

and let your button action set the zoom, keeping the same center:

- (IBAction)changeRegion:(id)sender {
    MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(self.mapView.centerCoordinate, 200.0f, 200.0f);
    [self.mapView setRegion:region animated:YES];
}

And very important: do not set your mapView to track user. Disable tracking user because now you are tracking it yourself. I think the default is MKUserTrackingModeNone .

like image 161
The dude Avatar answered Oct 19 '22 06:10

The dude