且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何在MKMapView中将图钉和地图保持在移动叠加上方的中心

更新时间:2021-09-06 21:55:42

实际上,keithbhunter的代码很慢,因为除了更新区域快于其加载速度之外,地图还改变了高度,这会导致额外的开销!

Actually, keithbhunter's code is slow because besides updating the region faster than it can load it, the map is also changing height which causes extra overhead!

我更新了代码,使其运行流畅.

I updated the code so that it runs smooth.

使用此代码,我要做的是保持地图视图的大小不变,但是我移动中心点以补偿滑动视图的高度.

With this code what i do is keep the map view the same size but instead i move the point of center to compensate for the height of the sliding view.

要使此代码正常工作,您必须修改keithbhunter的设置,以便将mapView的底部约束完全固定在超级视图的底部(而不是滑动视图)(这样,mapView的大小始终与超级视图相同).其余设置相同.

For this code to work, you have to modify keithbhunter's setup so that the mapView's bottom constraint is pinned completely to the superview's bottom (and not to the slidingView (so that the mapView is always the same size as the super view). For the rest the setup is the same.

还可以使用变量maxMetersDistance

在这里,我一直以埃菲尔铁塔为中心

Here i'm, always centering on the Eifel tower

import UIKit
import MapKit

class ViewController: UIViewController {

    @IBOutlet weak var mapView: MKMapView!
    @IBOutlet weak var slidingView: UIView!
    @IBOutlet weak var slidingViewHeight: NSLayoutConstraint!
    var maxMetersDistance:CGFloat = 10000.0; // customize this to set how far the map zooms out of the interest area

    override func viewDidLoad() {
        super.viewDidLoad()
        let pan = UIPanGestureRecognizer(target: self, action: "viewDidPan:")
        self.slidingView.addGestureRecognizer(pan)
        firstTimeCenter()
    }

    func firstTimeCenter(){
         var coordinate = CLLocationCoordinate2D(latitude: 48.8582, longitude: 2.2945)
        let region = MKCoordinateRegionMakeWithDistance(coordinate, Double(maxMetersDistance), Double(maxMetersDistance))
        self.mapView.setRegion(region, animated: true)
    }

    func reloadMap() {
        let height = CGFloat(self.slidingViewHeight.constant)
        var regionDistance = (maxMetersDistance / self.view.frame.height) * height
        regionDistance = maxMetersDistance - regionDistance
        var coordinate = CLLocationCoordinate2D(latitude: 48.8582, longitude: 2.2945)
        var mapRect = mapView.visibleMapRect;
        var metersPerMapPoint = MKMetersPerMapPointAtLatitude(coordinate.latitude);
        var metersPerPixel = CGFloat(metersPerMapPoint) * CGFloat(mapRect.size.width) / CGFloat(mapView.bounds.size.width);
        var totalMeters = Double(metersPerPixel) * Double(height/2)

        coordinate = self.translateCoord(coordinate, MetersLat: -totalMeters, MetersLong: 0.0)

        let region = MKCoordinateRegionMakeWithDistance(coordinate, Double(regionDistance), Double(regionDistance))
        self.mapView.setRegion(region, animated: false)
    }

    func viewDidPan(panGesture: UIPanGestureRecognizer) {
        let location = panGesture.locationInView(self.view)
        self.slidingViewHeight.constant = self.view.frame.size.height - location.y
        self.reloadMap()
    }

    func translateCoord(coord:CLLocationCoordinate2D, MetersLat:Double,  MetersLong:Double)->CLLocationCoordinate2D{
        var tempCoord = CLLocationCoordinate2D()
        var tempRegion = MKCoordinateRegionMakeWithDistance(coord, MetersLat, MetersLong);
        var tempSpan = tempRegion.span;
        tempCoord.latitude = coord.latitude + tempSpan.latitudeDelta;
        tempCoord.longitude = coord.longitude + tempSpan.longitudeDelta;
        return tempCoord;
    }

}