如何像Apple的Maps.app那样在MKMapView缩放时显示地图比例尺

问题描述 投票:0回答:3

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

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

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

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

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

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

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

提前致谢。

ios mkmapview mapkit
3个回答
1
投票

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

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

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

最后您可以更改海拔高度的格式,例如从 km 到 m 超过一定高度(10'000 米以下)。

对于老式学校:1m = 3.2808399 ft.

-(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]];
}



}

0
投票

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

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

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

region
属性和从中得出你的地图比例尺。


0
投票

正如您所了解的,方法

func mapView(_ mapView: MKMapView, regionWillChangeAnimated animated: Bool)
func mapView(_ mapView: MKMapView, regionDidChangeAnimated animated: Bool) 

当您开始和结束缩放手势时触发。 但是使用委托方法

func mapViewDidChangeVisibleRegion(_ mapView: MKMapView)

当缩放发生变化时,您会获得持续更新。

© www.soinside.com 2019 - 2024. All rights reserved.