Vla*_*mir 34 iphone zoom mkmapview
问题是 - 有没有办法限制MKMapView的最大缩放级别?或者有没有办法跟踪用户何时缩放到没有可用地图图像的级别?
Ted*_*ery 30
如果您只使用iOS 7+,则camera.altitude可以获取/设置一个新属性来强制执行缩放级别.它等同于azdev的解决方案,但不需要外部代码.
在测试中,我还发现,如果您反复尝试放大细节,则可以进入无限循环,因此我在下面的代码中有一个var来防止这种情况.
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
    // enforce maximum zoom level
    if (_mapView.camera.altitude < 120.00 && !_modifyingMap) {
        _modifyingMap = YES; // prevents strange infinite loop case
        _mapView.camera.altitude = 120.00;
        _modifyingMap = NO;
    }
}
nev*_*ing 29
您可以使用mapView:regionWillChangeAnimated:委托方法来侦听区域更改事件,如果区域比最大区域宽,请将其设置回最大区域,setRegion:animated:以向用户表明它们无法缩小到那么远.这是方法:
- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated
- (void)setRegion:(MKCoordinateRegion)region animated:(BOOL)animated
T. *_*kle 21
我只是花了一些时间来处理我正在构建的应用程序.这是我想出的:
我添加了一个返回当前缩放级别的方法.
在MKMapView + ZoomLevel.h中:
- (double)getZoomLevel;
在MKMapView + ZoomLevel.m中:
// Return the current map zoomLevel equivalent, just like above but in reverse
- (double)getZoomLevel{
    MKCoordinateRegion reg=self.region; // the current visible region
    MKCoordinateSpan span=reg.span; // the deltas
    CLLocationCoordinate2D centerCoordinate=reg.center; // the center in degrees
    // Get the left and right most lonitudes
    CLLocationDegrees leftLongitude=(centerCoordinate.longitude-(span.longitudeDelta/2));
    CLLocationDegrees rightLongitude=(centerCoordinate.longitude+(span.longitudeDelta/2));
    CGSize mapSizeInPixels = self.bounds.size; // the size of the display window
    // Get the left and right side of the screen in fully zoomed-in pixels
    double leftPixel=[self longitudeToPixelSpaceX:leftLongitude]; 
    double rightPixel=[self longitudeToPixelSpaceX:rightLongitude];
    // The span of the screen width in fully zoomed-in pixels
    double pixelDelta=abs(rightPixel-leftPixel);
    // The ratio of the pixels to what we're actually showing
    double zoomScale= mapSizeInPixels.width /pixelDelta;
    // Inverse exponent
    double zoomExponent=log2(zoomScale);
    // Adjust our scale
    double zoomLevel=zoomExponent+20; 
    return zoomLevel;
}
此方法依赖于上面链接的代码中的一些私有方法.
我将此添加到我的MKMapView委托中(如上面推荐的@vladimir)
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
    NSLog(@"%f",[mapView getZoomLevel]);
    if([mapView getZoomLevel]<10) {
        [mapView setCenterCoordinate:[mapView centerCoordinate] zoomLevel:10 animated:TRUE];
    }
}
如果用户太远,这会产生重新缩放的效果.您可以使用regionWillChangeAnimated来阻止地图"反弹".
关于上面的循环注释,看起来这个方法只迭代一次.
azd*_*dev 13
是的,这是可行的.首先,使用MKMapView + ZoomLevel扩展MKMapView .
然后,在MKMapViewDelegate中实现:
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
{
    // Constrain zoom level to 8.
    if( [mapView zoomLevel] < 8 )
    {
        [mapView setCenterCoordinate:mapView.centerCoordinate 
            zoomLevel:8 
            animated:NO];
    }
}
小智 7
这里是使用MKMapView + ZoomLevel和@ T.Markle回答在Swift 3中重写的代码:
import Foundation
import MapKit
fileprivate let MERCATOR_OFFSET: Double = 268435456
fileprivate let MERCATOR_RADIUS: Double = 85445659.44705395
extension MKMapView {
    func getZoomLevel() -> Double {
        let reg = self.region
        let span = reg.span
        let centerCoordinate = reg.center
        // Get the left and right most lonitudes
        let leftLongitude = centerCoordinate.longitude - (span.longitudeDelta / 2)
        let rightLongitude = centerCoordinate.longitude + (span.longitudeDelta / 2)
        let mapSizeInPixels = self.bounds.size
        // Get the left and right side of the screen in fully zoomed-in pixels
        let leftPixel = self.longitudeToPixelSpaceX(longitude: leftLongitude)
        let rightPixel = self.longitudeToPixelSpaceX(longitude: rightLongitude)
        let pixelDelta = abs(rightPixel - leftPixel)
        let zoomScale = Double(mapSizeInPixels.width) / pixelDelta
        let zoomExponent = log2(zoomScale)
        let zoomLevel = zoomExponent + 20
        return zoomLevel
    }
    func setCenter(coordinate: CLLocationCoordinate2D, zoomLevel: Int, animated: Bool) {
        let zoom = min(zoomLevel, 28)
        let span = self.coordinateSpan(centerCoordinate: coordinate, zoomLevel: zoom)
        let region = MKCoordinateRegion(center: coordinate, span: span)
        self.setRegion(region, animated: true)
    }
    // MARK: - Private func
    private func coordinateSpan(centerCoordinate: CLLocationCoordinate2D, zoomLevel: Int) -> MKCoordinateSpan {
        // Convert center coordiate to pixel space
        let centerPixelX = self.longitudeToPixelSpaceX(longitude: centerCoordinate.longitude)
        let centerPixelY = self.latitudeToPixelSpaceY(latitude: centerCoordinate.latitude)
        // Determine the scale value from the zoom level
        let zoomExponent = 20 - zoomLevel
        let zoomScale = NSDecimalNumber(decimal: pow(2, zoomExponent)).doubleValue
        // Scale the map’s size in pixel space
        let mapSizeInPixels = self.bounds.size
        let scaledMapWidth = Double(mapSizeInPixels.width) * zoomScale
        let scaledMapHeight = Double(mapSizeInPixels.height) * zoomScale
        // Figure out the position of the top-left pixel
        let topLeftPixelX = centerPixelX - (scaledMapWidth / 2)
        let topLeftPixelY = centerPixelY - (scaledMapHeight / 2)
        // Find delta between left and right longitudes
        let minLng: CLLocationDegrees = self.pixelSpaceXToLongitude(pixelX: topLeftPixelX)
        let maxLng: CLLocationDegrees = self.pixelSpaceXToLongitude(pixelX: topLeftPixelX + scaledMapWidth)
        let longitudeDelta: CLLocationDegrees = maxLng - minLng
        // Find delta between top and bottom latitudes
        let minLat: CLLocationDegrees = self.pixelSpaceYToLatitude(pixelY: topLeftPixelY)
        let maxLat: CLLocationDegrees = self.pixelSpaceYToLatitude(pixelY: topLeftPixelY + scaledMapHeight)
        let latitudeDelta: CLLocationDegrees = -1 * (maxLat - minLat)
        return MKCoordinateSpan(latitudeDelta: latitudeDelta, longitudeDelta: longitudeDelta)
    }
    private func longitudeToPixelSpaceX(longitude: Double) -> Double {
        return round(MERCATOR_OFFSET + MERCATOR_RADIUS * longitude * M_PI / 180.0)
    }
    private func latitudeToPixelSpaceY(latitude: Double) -> Double {
        if latitude == 90.0 {
            return 0
        } else if latitude == -90.0 {
            return MERCATOR_OFFSET * 2
        } else {
            return round(MERCATOR_OFFSET - MERCATOR_RADIUS * Double(logf((1 + sinf(Float(latitude * M_PI) / 180.0)) / (1 - sinf(Float(latitude * M_PI) / 180.0))) / 2.0))
        }
    }
    private func pixelSpaceXToLongitude(pixelX: Double) -> Double {
        return ((round(pixelX) - MERCATOR_OFFSET) / MERCATOR_RADIUS) * 180.0 / M_PI
    }
    private func pixelSpaceYToLatitude(pixelY: Double) -> Double {
        return (M_PI / 2.0 - 2.0 * atan(exp((round(pixelY) - MERCATOR_OFFSET) / MERCATOR_RADIUS))) * 180.0 / M_PI
    }
}
在视图控制器中使用的示例:
func mapView(_ mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
        print("Zoom: \(mapView.getZoomLevel())")
        if mapView.getZoomLevel() > 6 {
            mapView.setCenter(coordinate: mapView.centerCoordinate, zoomLevel: 6, animated: true)
        }
    }
小智 5
使用此示例可以锁定最大变焦范围,同样您可以限制最小变焦范围
map.cameraZoomRange = MKMapView.CameraZoomRange(最大中心坐标距离:1200000)
| 归档时间: | 
 | 
| 查看次数: | 31157 次 | 
| 最近记录: |