如何检测mapView在Swift中移动并更新缩放

时间:2016-01-13 16:39:03

标签: ios swift mkmapview

我正在尝试在Swift 2中的地图上设置最小缩放级别。我找不到任何关于如何限制地图被放大太远的文档。我决定尝试的是监视对于地图移动(例如拖动或缩放),然后将onActivityResult设置为最小值。

我发现MKZoomScale的大多数答案都在Objective C中,我不知道,而且我将它们转换为Swift时遇到了麻烦。

我尝试实现@ hEADcRASH的答案:https://stackoverflow.com/a/30924768/4106552,但在地图在模拟器中移动时,它不会触发并向控制台打印任何内容。

谁能告诉我我做错了什么?我是Swift的新手,所以这可能是一个小错误。另外,让我知道是否有一种轻量级方法来解决限制地图上的缩放级别。我担心移动监视器会慢慢减慢地图动画的速度。谢谢你的帮助。

这是我的视图控制器。     导入UIKit     导入Parse     导入MapKit

regionDidChangeAnimated

1 个答案:

答案 0 :(得分:4)

在审查并结合了许多其他问题/答案以及@lorenzoliveto的帮助之后,我已经在Swift中工作了。如果有更好/更轻量级的方法来实现同样的目的,请发表评论。

我将self.map.delegate = self添加到viewDidLoad函数。

以下是我如何监控地图移动的代码,然后一旦用户放大“太远”并且地图的宽度低于2英里,我就会使用mapView.setRegion缩小地图

private var mapChangedFromUserInteraction = false

private func mapViewRegionDidChangeFromUserInteraction() -> Bool {
    let view = self.map.subviews[0]
    //  Look through gesture recognizers to determine whether this region change is from user interaction
    if let gestureRecognizers = view.gestureRecognizers {
        for recognizer in gestureRecognizers {
            if( recognizer.state == UIGestureRecognizerState.Began || recognizer.state == UIGestureRecognizerState.Ended ) {
                return true
            }
        }
    }
    return false
}

func mapView(mapView: MKMapView, regionWillChangeAnimated animated: Bool) {
    mapChangedFromUserInteraction = mapViewRegionDidChangeFromUserInteraction()
    if (mapChangedFromUserInteraction) {
        // user will change map region
        print("user WILL change map.")

        // calculate the width of the map in miles.
        let mRect: MKMapRect = mapView.visibleMapRect
        let eastMapPoint = MKMapPointMake(MKMapRectGetMinX(mRect), MKMapRectGetMidY(mRect))
        let westMapPoint = MKMapPointMake(MKMapRectGetMaxX(mRect), MKMapRectGetMidY(mRect))
        let currentDistWideInMeters = MKMetersBetweenMapPoints(eastMapPoint, westMapPoint)
        let milesWide = currentDistWideInMeters / 1609.34  // number of meters in a mile
        print(milesWide)
        print("^miles wide")

        // check if user zoomed in too far and zoom them out.
        if milesWide < 2.0 {
            var region:MKCoordinateRegion = mapView.region
            var span:MKCoordinateSpan = mapView.region.span
            span.latitudeDelta = 0.04
            span.longitudeDelta = 0.04
            region.span = span;
            mapView.setRegion(region, animated: true)
            print("map zoomed back out")
        }

    }
}

func mapView(mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
    if (mapChangedFromUserInteraction) {
        // user changed map region
        print("user CHANGED map.")
        print(mapView.region.span.latitudeDelta)
        print(mapView.region.span.longitudeDelta)

        // calculate the width of the map in miles.
        let mRect: MKMapRect = mapView.visibleMapRect
        let eastMapPoint = MKMapPointMake(MKMapRectGetMinX(mRect), MKMapRectGetMidY(mRect))
        let westMapPoint = MKMapPointMake(MKMapRectGetMaxX(mRect), MKMapRectGetMidY(mRect))
        let currentDistWideInMeters = MKMetersBetweenMapPoints(eastMapPoint, westMapPoint)
        let milesWide = currentDistWideInMeters / 1609.34  // number of meters in a mile
        print(milesWide)
        print("^miles wide")

        // check if user zoomed in too far and zoom them out.
        if milesWide < 2.0 {
            var region:MKCoordinateRegion = mapView.region
            var span:MKCoordinateSpan = mapView.region.span
            span.latitudeDelta = 0.04
            span.longitudeDelta = 0.04
            region.span = span;
            mapView.setRegion(region, animated: true)
            print("map zoomed back out")
        }
    }

更新:3/7,我在上面的实现中发现了一个有趣的错误。在模拟器上,单击缩放时可以正常工作,但是当您使用缩放进行缩放(选项+单击)时,模拟器将停止,允许您在缩小动画后将其拖动。这也发生在我的iphone的测试版上。我在块周围添加了dispatch_async,将该地图的动画恢复到它们的位置,它似乎正在模拟器上运行。它动画后不再显示为冻结,我可以继续拖动地图并尝试放大。

dispatch_async(dispatch_get_main_queue(), {
   var region:MKCoordinateRegion = mapView.region
   var span:MKCoordinateSpan = mapView.region.span
   span.latitudeDelta = 0.04
   span.longitudeDelta = 0.04
   region.span = span;
   mapView.setRegion(region, animated: true)
   print("map zoomed back out")
})