3

This is a small method of mine which takes the location manager's current location and focuses the map just a little bit above it to make room for some other subviews that I've added to the top of the map. If the span's lat/long deltas get too big (more than 1.0), every time the region is set, the span gets bigger and bigger until the map is zoomed out all the way, even without actually touching the map. I think it has something to do with reusing the map view's span, but I don't know exactly what's going on.

- (void)setRegion {
    CLLocationCoordinate2D coord = locationManager.location.coordinate;

    MKCoordinateSpan span = mapView.region.span;

    coord.latitude += 0.002 * (span.latitudeDelta / 0.012523);

    MKCoordinateRegion region = MKCoordinateRegionMake(coord, span);
    [mapViewGlobal setRegion:region animated:animated];
}
eric.mitchell
  • 8,817
  • 12
  • 54
  • 92
  • The resulting span after `setRegion:animated:` can be a little different than the input span. This is a known issue of MKMapView. In your case maybe the span gets bigger every time. – Felix Aug 21 '12 at 19:45
  • I know that the resulting span isn't the exact same, but it my case I have the map zoomed far enough in so that you can see individual cities, and in 4-5 iterations of this method the map is zoomed all the way out, without even touching the map itself. – eric.mitchell Aug 21 '12 at 19:47
  • Where does the variable "animated" come from? Is it YES or NO? – Felix Aug 21 '12 at 20:29

1 Answers1

4

From Apple's docs "If you want to change the center coordinate without changing the zoom level, use the setCenterCoordinate:animated: instead." MKMapView

- (void)setCenterCoordinate:(CLLocationCoordinate2D)coordinate animated:(BOOL)animated

MKMapView will pick a new region that nicely fits the to a redefined zoom level while still displaying your entire target region and each time yo move north the span changes and things spiral out of control.

Also, your way of working out how much to change the latitude by is a bit odd. Aside from doing a multiple and divide when one would do the trick, it'll only work at a certain latitude (they get stretched away from the equator) and a certain zoom level. You'd be better off working out how many pixels you need the map scrolled by (presumably half the height of your subviews) and then using this function to work out where you need to center the map.

- (CLLocationCoordinate2D)convertPoint:(CGPoint)point toCoordinateFromView:(UIView *)view

Another way would be to put the subviews outside of the MKMapView, but that'll affect your aesthetics.

Craig
  • 8,093
  • 8
  • 42
  • 74
  • Awesome. `setCenterCoordinate:` is perfect. I don't exactly understand how I would use `convertPoint:` to focus the map so that the coordinate is horizontally centered but positioned with a y value of 2/3 the map's height as opposed to 1/2. – eric.mitchell Aug 22 '12 at 11:36
  • If you want your annotation to be centered in the area not covered by the subviews you need to make the map look at a different center point. If the subviews are 100px at the top of a 600px mapview, your annotation needs to be 50px below the center. Regardless of how much that is in degrees it is the px count that you want (unless your subviews are measured in degrees). So, find out the coordinates of the screen point 50px above your centered annotation and pan to that, thus moving your annotation 50px south and into the middle of the non-subviewd area. – Craig Aug 22 '12 at 19:12