【问题标题】:how to show map scale during zoom of MKMapView like Apple's Maps.app如何在缩放 MKMapView 时显示地图比例,如 Apple 的 Maps.app
【发布时间】:2013-10-24 17:15:07
【问题描述】:

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

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

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

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

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

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

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

提前致谢。

【问题讨论】:

    标签: ios mkmapview mapkit


    【解决方案1】:

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

    由于没有诸如“regionISChangeingAnimated”之类的方法,而只有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]];
    }
    
    
    
    }
    

    【讨论】:

      【解决方案2】:

      来自 Apple 关于 MKMapView 的 regionWillChangeAnimated: 方法的文档(重点是我的):

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

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

      【讨论】:

      • 与文档所说的相反,此方法不是连续调用,而是在原始帖子中所述缩放开始时调用一次。
      猜你喜欢
      • 2013-07-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-16
      • 2012-09-19
      相关资源
      最近更新 更多