我在iPhone上使用MapKit。 如何知道用户何时更改缩放级别(放大\ out the map)?
我尝试使用 mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)动画; 但即使只拖动地图也会调用它。 不幸的是,当拖动地图时,mapView.region.span也会发生变化......
帮助?
10倍
答案 0 :(得分:35)
计算缩放级别非常简单。请参阅下面的代码段。您可以从visibleMapRect
实例的MKMapView
属性中获取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关于这个话题的优秀博客文章中找到了这些东西:
http://troybrant.net/blog/2010/01/mkmapview-and-zoom-levels-a-visual-guide/
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))
}
}
答案 1 :(得分:11)
我发现这非常有用,并根据这些答案开发了以下代码。
- (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];
}
}
}
答案 2 :(得分:2)
我有以下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];
}
答案 3 :(得分:1)
您可以听取mapView:regionDidChangeAnimated:
方法。但是,这并不会告诉您缩放级别是否已更改,只是地图已设置动画。
您还需要侦听地图视图的region
属性。它包含latitudeDelta和longitudeDelta值,可用于计算缩放级别是否已更改。
即。在.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");
}
这应检测地图缩放是否已更改。
然而,你应该为变焦而改变因为地球是弯曲的:(如果滚动地图,纬度Delta和longitudeDelta会因为地球的形状而稍微改变,而不是因为用户已经放大了。你可能会必须检测增量的大变化并忽略轻微的变化。
希望有所帮助。
答案 4 :(得分:1)
更简单的答案:
获取当前缩放级别的Integer的最简单方法是使用MapView函数:regionDidChangeAnimated。此功能可识别缩放的每个变化,并为您提供缩放系数计算的基础。
只需将此函数插入MapView类(适用于Swift 3.0 ):
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)")
}
你会得到一个zoomFactor值,其中0是你可以放大到地图的最近点,每个更高的值都是遥远的缩放......: - )
答案 5 :(得分:0)
计算MKMapView中的缩放比例 - Swift解决方案
我为MKMapView创建了以下扩展,因此您可以在地图上获得缩放比例。解决方案类似于上面提到的但在Swift中。
还有一个额外的函数scaleWithPrecision(_:Int64)
用于舍入可以过滤掉f.ex的缩放比例。 MapView上的小变焦变化
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
}
}
答案 6 :(得分:-1)
您可以保存纬度增量,然后在调用regionDidChangeAnimated:
时,检查新的纬度增量是否不同。我认为只要地图没有缩放,纬度增量就会保持不变。