2

我在我的自定义应用程序中使用 MKMapView,并希望在缩放过程中显示地图比例(卷尺),如 Apple 的 Maps.app。这可能吗?

如果没有,我将实现自己的地图比例,如何在 MKMapView 的缩放发生变化时获得持续的更新信息?

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

似乎在缩放开始时只被调用一次,而

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

在缩放结束时只调用一次。

Maps.app 地图比例在缩放过程中不断实时显示和更新。

提前致谢。

4

2 回答 2

1

我遇到了类似的问题,根据用户缩放获取 camera.altitude 以显示在标签中。

由于没有“regionISChangingAnimated”之类的方法,而只有 WillChange 和 DidChange,所以我在 WillChange 处启动了一个计时器,并在 DidChange 处使其无效。计时器调用一个方法 (updateElevationLabel) 来计算相机在地图上方的高度。

但是,由于在调用 regionDidChange 之前不会计算 camera.altitude,因此使用缩放比例和地图的起始高度(缩放比例 = 1.0 并不总是等于高度 = 0m,这取决于您在世界的哪个位置)来计算当前高度。在下面的方法中,起始高度是一个浮点数,在加载时设置一次,并针对每个区域更改。

最后,您可以更改高度的格式,例如从 km 到 m 超出某个高度(10'000 米以下)。

对于老派:1m = 3.2808399 英尺。

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

    if (showsElevation) {

    //update starting height for the region
    MKMapCamera *camera = map.camera;
    CLLocationDistance altitude = camera.altitude;
    MKZoomScale currentZoomScale = map.bounds.size.width / map.visibleMapRect.size.width;
    float factor = 1.0/currentZoomScale;
    startingHeight = altitude/factor;

    elevationTimer = [NSTimer scheduledTimerWithTimeInterval:0.1
                                                      target:self
                                                    selector:@selector(updateElevationLabel)
                                                    userInfo:Nil
                                                     repeats:YES];
    [elevationTimer fire];

    }
}

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

    [elevationTimer invalidate];
}


-(void)updateElevationLabel {


//1. create the label
if (!elevationLabel) {
    elevationLabel = [UILabel new];
    [elevationLabel setFrame:CGRectMake(0, 18, 200, 44)];
    [elevationLabel setBackgroundColor:[UIColor redColor]];
    [self addSubview:elevationLabel];
}

//2. grab the initial starting height (further updated on region changes)
if (startingHeight == 0) {
    MKMapCamera *camera = map.camera;
    CLLocationDistance altitude = camera.altitude;
    MKZoomScale currentZoomScale = map.bounds.size.width / map.visibleMapRect.size.width;
    float factor = 1.0/currentZoomScale;
    startingHeight = altitude/factor;
}

//3. get current zoom scale and altitude, format changes
MKZoomScale currentZoomScale = map.bounds.size.width / map.visibleMapRect.size.width;
float altitude = startingHeight * (1/currentZoomScale);
if (altitude>10000) {
    altitude = altitude/1000;
        [elevationLabel setText:[NSString stringWithFormat:@"%.1fkm", altitude]];
} else {
        [elevationLabel setText:[NSString stringWithFormat:@"%.0fm", altitude]];
}



}
于 2014-03-03T15:17:34.610 回答
0

来自 Apple 关于 MKMapView 的 regionWillChangeAnimated: 方法的文档(强调我的):

每当当前显示的地图区域发生变化时,都会调用此方法。在滚动过程中,可能会多次调用此方法来报告地图位置的更新。因此,您对该方法的实现应尽可能轻量级,以避免影响滚动性能。

听起来您应该能够在地图视图滚动时连续使用此方法,这解决了您的部分问题 - 因此,当调用该方法时,请查看(我在这里猜测)mapview 的region属性并得出您的地图比例从此。

于 2013-10-24T17:24:57.247 回答