Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/43.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 检查缩放级别是否已更改_Iphone_Objective C_Iphone Sdk 3.0_Mapkit_Mkmapview - Fatal编程技术网

Iphone 检查缩放级别是否已更改

Iphone 检查缩放级别是否已更改,iphone,objective-c,iphone-sdk-3.0,mapkit,mkmapview,Iphone,Objective C,Iphone Sdk 3.0,Mapkit,Mkmapview,我正在iPhone上使用MapKit。 我如何知道用户何时更改缩放级别(放大/缩小地图) 我尝试过使用mapView:(MKMapView*)mapView区域IDChangeAnimated:(BOOL)animated但即使仅拖动贴图,也会调用该函数。 不幸的是,当拖动地图时,mapView.region.span也会更改 帮忙 10x您可以保存一个纬度增量,然后在调用regionDidChangeAnimated:时,检查新的纬度增量是否不同。我认为只要地图不缩放,纬度增量就保持不变。您可

我正在iPhone上使用MapKit。 我如何知道用户何时更改缩放级别(放大/缩小地图)

我尝试过使用mapView:(MKMapView*)mapView区域IDChangeAnimated:(BOOL)animated但即使仅拖动贴图,也会调用该函数。 不幸的是,当拖动地图时,mapView.region.span也会更改

帮忙


10x

您可以保存一个纬度增量,然后在调用
regionDidChangeAnimated:
时,检查新的纬度增量是否不同。我认为只要地图不缩放,纬度增量就保持不变。

您可以收听
mapView:RegiondChangeAnimated:
方法。但是,这不会告诉您缩放级别是否更改,只是在贴图已设置动画的情况下

您还需要收听地图视图的
区域
属性。其中包含latitudeDelta和LongtudeDelta值,可用于计算缩放级别是否已更改

i、 在.h文件中

@class MyMapViewController {
    ...
    MKCoordinateRegion mapRegion;
    }
@end
在你的.m文件中

- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated {
    mapRegion = mapView.region;
}

- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
    newRegion = mapView.region;

    if (mapRegion.span.latitudeDelta != newRegion.span.latitudeDelta ||
        mapRegion.span.longitudeDelta != newRegion.span.longitudeDelta)
        NSLog(@"The zoom has changed");
}
这将检测地图缩放是否已更改

但是,由于地球是弯曲的,您应该停止缩放更改:(如果滚动地图,则latitudeDelta和LongtudeDelta将仅因地球的形状而发生轻微变化,而不是因为用户已缩放。您可能必须检测到三角洲中的大变化,而忽略微小变化


希望对您有所帮助。

计算缩放级别非常简单。请参阅下面的代码段。您可以从
MKMapView
实例的
visibleMapRect
属性中获取mRect参数

+ (NSUInteger)zoomLevelForMapRect:(MKMapRect)mRect withMapViewSizeInPixels:(CGSize)viewSizeInPixels
{
    NSUInteger zoomLevel = MAXIMUM_ZOOM; // MAXIMUM_ZOOM is 20 with MapKit
    MKZoomScale zoomScale = mRect.size.width / viewSizeInPixels.width; //MKZoomScale is just a CGFloat typedef
    double zoomExponent = log2(zoomScale);
    zoomLevel = (NSUInteger)(MAXIMUM_ZOOM - ceil(zoomExponent));
    return zoomLevel;
}
您可能只需停止计算
zoomScale
的步骤,因为这将告诉您缩放是否发生了任何变化

我通过阅读特洛伊·布兰茨(Troy Brants)关于这一主题的优秀博客文章了解到了这一点:

Swift 3

extension MKMapView {

    var zoomLevel: Int {
        let maxZoom: Double = 20
        let zoomScale = self.visibleMapRect.size.width / Double(self.frame.size.width)
        let zoomExponent = log2(zoomScale)
        return Int(maxZoom - ceil(zoomExponent))
    }

}

我发现这非常有用,并根据这些答案开发了以下代码

- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated 
{
   mapRegion = self.mapView.region;
}


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

MKCoordinateRegion newRegion = self.mapView.region;

NSInteger zFactor;
if ((mapRegion.span.latitudeDelta/newRegion.span.latitudeDelta) > 1.5){
    NSLog(@"Zoom in changed");
    zFactor = 20;
    CustomPlacemark *aO; 
    MKAnnotationView *aV; 
    for (aO in self.mapView.annotations) {
        aV = [[self mapView] viewForAnnotation:aO];
        aV.frame = CGRectMake(aV.frame.origin.x, aV.frame.origin.y, aV.frame.size.width+zFactor, aV.frame.size.height+zFactor);
        [[[self mapView] viewForAnnotation:aO] setFrame:aV.frame];
    }
}
if ((mapRegion.span.latitudeDelta/newRegion.span.latitudeDelta) < 0.75){
    NSLog(@"Zoom out");
    zFactor = -20;
    CustomPlacemark *aO; 
    MKAnnotationView *aV; 
    for (aO in self.mapView.annotations) {
        aV = [[self mapView] viewForAnnotation:aO];
        aV.frame = CGRectMake(aV.frame.origin.x, aV.frame.origin.y, aV.frame.size.width+zFactor, aV.frame.size.height+zFactor);
        [[[self mapView] viewForAnnotation:aO] setFrame:aV.frame];
    }
  }
}
-(void)地图视图:(MKMapView*)地图视图区域将更改动画:(BOOL)动画
{
mapRegion=self.mapView.region;
}
-(void)地图视图:(MKMapView*)地图视图区域IDChangeAnimated:(BOOL)动画{
MKCoordinateRegion newRegion=self.mapView.region;
NSInteger因子;
如果((mapRegion.span.latitudeDelta/newRegion.span.latitudeDelta)>1.5){
NSLog(“放大已更改”);
zFactor=20;
海关地标*aO;
MKAnnotationView*aV;
for(self.mapView.annotations中的aO){
aV=[[self mapView]viewForAnnotation:aO];
aV.frame=CGRectMake(aV.frame.origin.x,aV.frame.origin.y,aV.frame.size.WITH+zFactor,aV.frame.size.height+zFactor);
[[self mapView]viewForAnnotation:aO]设置帧:aV.frame];
}
}
if((mapRegion.span.latitudeDelta/newRegion.span.latitudeDelta)<0.75){
NSLog(“缩小”);
zFactor=-20;
海关地标*aO;
MKAnnotationView*aV;
for(self.mapView.annotations中的aO){
aV=[[self mapView]viewForAnnotation:aO];
aV.frame=CGRectMake(aV.frame.origin.x,aV.frame.origin.y,aV.frame.size.WITH+zFactor,aV.frame.size.height+zFactor);
[[self mapView]viewForAnnotation:aO]设置帧:aV.frame];
}
}
}

我有以下MKMapView类别,其中包括一种快速获取地图当前缩放级别的方法:

@implementation MKMapView (ZoomLevel)

- (NSUInteger) zoomLevel {
    MKCoordinateRegion region = self.region;

    double centerPixelX = [MKMapView longitudeToPixelSpaceX: region.center.longitude];
    double topLeftPixelX = [MKMapView longitudeToPixelSpaceX: region.center.longitude - region.span.longitudeDelta / 2];

    double scaledMapWidth = (centerPixelX - topLeftPixelX) * 2;
    CGSize mapSizeInPixels = self.bounds.size;
    double zoomScale = scaledMapWidth / mapSizeInPixels.width;
    double zoomExponent = log(zoomScale) / log(2);
    double zoomLevel = 21 - zoomExponent;

    return zoomLevel;
}

@end
要获得缩放级别,可以在代理中调用以下命令,并确定缩放级别是否已更改:

- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
    NSUInteger zoomLevel = [mapView zoomLevel];
}

在MKMapView中计算缩放比例-Swift解决方案

我为MKMapView创建了以下扩展,以便您可以在地图上获得缩放比例。解决方案与上面所示类似,但使用Swift

还有一个额外的函数
scaleWithPrecision(u:Int64)
用于对该比例进行四舍五入,使其能够过滤掉f.ex。地图视图上的小缩放更改

extension MKMapView {

    var scale: Double {

        return self.scaleWithPrecision(1)
    }

    func scaleWithPrecision(precision: Int64) -> Double {

        let mapBoundsWidth = Double(self.bounds.size.width)
        let mapRectWidth:Double = self.visibleMapRect.size.width

        let scale: Double = round(Double(precision)*mapBoundsWidth/mapRectWidth)/Double(precision)

        return scale
    }
}
更简单的答案是:

获取当前缩放级别整数的最简单方法是使用MapView函数:regionDidChangeAnimated。该函数可识别缩放中的每个更改,并为计算缩放因子提供依据

只需将此函数插入MapView类(适用于Swift 3.0):


你将从中得到一个zoomFactor值,其中0是你可以放大地图的最接近点,每一个更高的值都是一个很远的缩放…:-)

比我的答案更完整。我认为经度增量随着你向两极移动而变化,但是纬度增量在你去的任何地方都保持不变。可能需要一些测试来检查它是否足够稳定,以便使用。我永远记不起哪些更改和哪些不更改,所以我在回答中刚刚测试了这两种更改:)我想你可以测试看看他们是否会更改它必须是用户缩放,如果只有一个更改,它将是一个滚动?伙计们,我希望你们能稍微检查一下“解决方案”在发布之前。你的想法没有一个奏效。跨度增量确实发生了变化,而且变化很大。5分钟的测试告诉我,latitudeDelta一直在变化,Longtudedelta只有在缩放时才会发生变化,因此,如果只测试Longtudedelta,我的答案就会起作用。我们不是来帮你解决问题的,我们是来帮你自己找到解决方案的,我想我们已经找到了。没问题,我应该在我的回答中说明这是未经测试的:)好吧,你错了。拖动地图时,跨度值会发生变化。哇!这看起来正是我需要的。为了使事情变得更尖锐-我从哪里获得viewSizeInPixels?viewSizeInPixels是MKMapView实例的bounds.size属性非常有用,需要确定贴图是否已放大到最大值。谢谢。如果不是很明显,您可以从MKMapView实例的
visibleMapRect
属性获取
mapRect
。我尝试使用您的代码,但发现一些奇怪的事情。我做了一些调试,现在我很困惑
MKZoomScale zoomScale
retu
var mapView: MKMapView! = nil

...

func mapView(_ mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
    let zoomWidth = mapView.visibleMapRect.size.width
    let zoomFactor = Int(log2(zoomWidth)) - 9
    print("...REGION DID CHANGE: ZOOM FACTOR \(zoomFactor)")
}