如何动态设置 MKMapView 的区域跨度,使其在重绘地图时不会"snap"回初始区域?



我正在使用MKMapview,但缩放级别和区域跨度有问题。

刷新 MKMapView 时,它似乎会将区域重置为我最初安装它们时已硬编码的值。我正在跟踪用户的位置,随着电话位置的任何更改,地图应通过CLLocationManagerDelegate和下面列出的委托方法进行更新。

目前我在位置管理器中有一个:didUpdateToLocation:fromLocation:

    MKCoordinateSpan span;
    span.latitudeDelta =  0.8;  
    span.longitudeDelta = 0.8;     
    MKCoordinateRegion region;
    region.center = newLocation.coordinate;
    region.span = span;
    [self.MyMapView setRegion:region animated:NO];

我也尝试将类似的代码放在viewDidLoad中:无济于事。我的想法是,我可以以某种方式

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

委托方法 我可以完全回避这个问题,但我不确定我应该怎么做

最终,我只想让地图停止"捕捉"回上面的跨度。提前谢谢。

如果尝试将地图以用户的当前位置为中心,请首先决定是否要使用:

  • 地图视图的 userLocation 属性和地图视图的委托方法 mapView:didUpdateUserLocation: ,或
  • CLLocationManager及其委托方法locationManager:didUpdateToLocation:fromLocation:

对于其中任何一个,在viewDidLoad中,您应该只设置地图视图的初始区域,包括中心(使用一些默认坐标(和跨度。 用户的位置不太可能立即显示在viewDidLoad中,因为它可能需要几秒钟才能获得。

尝试在设置之前使用 userLocation 可能会导致使用该值设置区域时出现异常。

如果使用地图视图的userLocation,则:

  • 在视图中,将mapView.showsUserLocation设置为 YES
  • mapView:didUpdateUserLocation:方法中,执行mapView.centerCoordinate = userLocation.location.coordinate;(或使用setCenterCoordinate:animated:(
  • 还建议实施mapView:didFailToLocateUserWithError:来处理或至少意识到故障

如果使用CLLocationManager,则:

  • 在视图中DidLoad,执行[locationManager startUpdatingLocation];
  • locationManager:didUpdateToLocation:fromLocation:方法中,执行mapView.centerCoordinate = newLocation.coordinate;(或使用动画方法(
  • 还建议实施locationManager:didFailWithError:来处理或至少意识到故障

我能够通过创建一个UIViewController子类来保存MKMapView实例来解决这个问题。我在 loadView 中恢复了 mapView 的跨度,然后在 VC 的 viewWillAppear 方法中调用[mapView setUserTrackingMode:...]

看到了OP在之前的实现中描述的行为,其中我动态创建了一个VC和一个"MKMapView"实例,然后将其推送到我的导航控制器上。我永远无法同时设置跨度和设置用户跟踪以跟随用户而不会丢失跨度。我做了一些调试,甚至看到在显示视图时原始跨度值被丢弃,所以我认为这与设置跨度或设置用户跟踪模式有关,而没有显示视图。无论如何,按照上述方式组织代码解决了问题。

以下是相关位:

// ===== mainVC.h =====
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
@interface MapVC : UIViewController <MKMapViewDelegate>
@end
// ===== mainVC.m =====   
static MapVC *map = nil;
- (void)mapAction {
    UINavigationController *nav = [self navigationController];
    // map VC is a singleton
    if (!map) map = [[MapVC alloc] init];
    [nav pushViewController:map animated:TRUE];
}

// ===== MapVC.m =====
- (void)loadView {
    mapView = [[MKMapView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    [mapView setDelegate:self];
    MKCoordinateSpan span = MKCoordinatSpanMake(storedLatitudeDelta, storedLongitudeDelta);
    [mapView setRegion:MKCoordinateRegionMake(storedCenter, span)];
    [self setView:mapView];
}
- (void)viewWillAppear:(BOOL)animated {
    [mapView setUserTrackingMode:MKUserTrackingModeFollow animated:TRUE];
}
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
    MKCoordinateSpan mySpan = [mapView region].span;
    storedLatitudeDelta = mySpan.latitudeDelta;
    storedLongitudeDelta = mySpan.longitudeDelta;
}

我从一个更大的项目中修剪了它,所以如果你看到任何错别字,请告诉我,但这就是它的要点。