iOS - How to limit the MapView to a specific region?

让人想犯罪 __ 提交于 2019-11-27 03:06:37
Vincent Guerci

By implementing :

-(void) mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated

You should be able to reset region to your specific one.

Look at that answer to have an example of how to do this.


Another solution, that brings more precise events but is more complex (I'm currently using this successfully for another need) is to subclass MKMapView and override UIScrollViewDelegate protocol.

If you do that, make sure to call super implementation like that :

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
  if ([super respondsToSelector:@selector(scrollViewWillBeginDragging:)])
    [super scrollViewWillBeginDragging:scrollView];
  // do what you want
}

Note: While the protocol is public, MKMapView implementation is unknown and might differ with iOS versions, so it is more safe to check with respondsToSelector: before. You must call super implementations or Map will just not work properly.

mrdavenz

After trying different ways of limited MKMapView I've concluded that using mapDidChange, and resetting if you're center point goes outside of the boundaries works best, with animated: YES

Here's how I do it (Using the New Zealand lat/Long span/center).

- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated{ 
  if ((mapView.region.span.latitudeDelta > 15.589921 ) || (mapView.region.span.longitudeDelta > 175.836914) ) {
    CLLocationCoordinate2D centerCoord = CLLocationCoordinate2DMake(-41.162114, 172.836914);

    MKCoordinateSpan spanOfNZ = MKCoordinateSpanMake(13.589921, 14.062500 );

    MKCoordinateRegion NZRegion = MKCoordinateRegionMake(centerCoord, spanOfNZ);

    [mapView setRegion: NZRegion animated: YES];
  }

 if (abs(abs(mapView.region.center.latitude) - 41.162114) > (13.589921 / 2) ) {
    CLLocationCoordinate2D centerCoord = CLLocationCoordinate2DMake(-41.162114, 172.836914);

    MKCoordinateSpan spanOfNZ = MKCoordinateSpanMake(13.589921, 14.062500 );

    MKCoordinateRegion NZRegion = MKCoordinateRegionMake(centerCoord, spanOfNZ);

    [mapView setRegion: NZRegion animated: YES];

  }

  if (abs(abs(mapView.region.center.longitude) - 172.836914) > (14.062500 / 2) ) {
    CLLocationCoordinate2D centerCoord = CLLocationCoordinate2DMake(-41.162114, 172.836914);

     MKCoordinateSpan  spanOfNZ = MKCoordinateSpanMake(13.589921, 14.062500 );

     MKCoordinateRegion NZRegion = MKCoordinateRegionMake(centerCoord, spanOfNZ);

     [mapView setRegion: NZRegion animated: YES];
  }
}
Ken Koch

I know this is a pretty old question, but to avoid the infinite loop you could try something like this: https://stackoverflow.com/a/4126011/1234011

Basically set a flag to prevent the callback from firing again if it was you who set the value.

  • Ken
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!