如何抵消MKMapView将坐标放在指定的点下

时间:2017-03-29 15:57:38

标签: ios swift mkmapview coordinates

我有两个视图控制器。一个允许用户输入他们自己的事物:

SubmitSightingsVC

另一个是UITableViewController,允许他们查看提交的目击事件:

SightingsEditVC

我想要的是让用户能够在第二个VC中点击他们的目击,并使用相关细节填充第一个VC。我使用以下方法为textFields工作:

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    let pvc = self.navigationController?.previousViewController() as! SubmitSightingVC
    let sighting = sightingsArray[indexPath.row]
    pvc.titleTextField.text = sighting["title"] as! String?
    pvc.locationTextField.text = sighting["location"] as! String?
    pvc.dateTextField.text = sighting["date"] as! String?
    pvc.descriptionTextView.text = sighting["sightingDesc"] as! String?

    let pinArray = ["1", "2", "3", "4", "5"]
    let pinTextArray = ["1text", "2text", "3text", "4text", "5text"]
    var pinImageArray = [#imageLiteral(resourceName: "1"), #imageLiteral(resourceName: "2"), #imageLiteral(resourceName: "3"), #imageLiteral(resourceName: "4"), #imageLiteral(resourceName: "5")]
    let pinIconString = sighting["pinIcon"] as! String
    let index = pinArray.index(of: pinIconString)

    pvc.pinImageView.image = pinImageArray[index!]
    pvc.pinTextField.text = pinTextArray[index!]


    // Bit I'm struggling with:
    var coordinates = CLLocationCoordinate2D(latitude: sighting["latitude"] as! Double, longitude: sighting["longitude"] as! Double)
    pvc.mapView.centerCoordinate = coordinates

    self.navigationController!.popViewController(animated: true)

}

问题是因为地图的中心位于模糊视图的后面,所以它是偏移的。地图上的图钉不是实际图钉,而是UIImage(pinImageView)。如何移动地图以使坐标位于此pinImage下而不是mapView的中心?

2 个答案:

答案 0 :(得分:2)

如上所述,你可以使用MKMapCamera来定位地图的视图,或者你也可以使用setVisibleMapRect并添加一些填充来定位地图,如下所示:

self.mapView.setVisibleMapRect(self.mapView.visibleMapRect, edgePadding: UIEdgeInsetsMake(200.0, 0.0, 0.0, 0.0), animated: true)

这将使中心偏移顶部200个屏幕像素。

答案 1 :(得分:0)

从优秀的@rmp 回答来看,总体思路是

self.map.setVisibleMapRect(self.map.visibleMapRect,
 edgePadding: UIEdgeInsets(top: -200, left: 0, bottom: 0, right: 0),
 animated: true)

将其“向上移动 200”。 但是,请注意算术并不是真正正确的。

要向上移动“框”,您必须在顶部负插入,在底部插入正插入。上面的代码会对框进行某种程度的拉伸和缩放(中心会向上移动,但会向上移动一个小于 200 的随机高度)。

所以你要做的是:

let UP = 170 // move it up 170
let LEFT = 50 // move it left 50

self.map.setVisibleMapRect(self.map.visibleMapRect,
 edgePadding: UIEdgeInsets(top: -UP, left: -LEFT, bottom: UP, right: LEFT),
 animated: true)

那行得通。

这是在地图上获取点的总公式,可能是城镇或房屋 coords

1. 很好地将其居中,无论当前的相机位置、角度、变焦等如何,然后

2. 将其向上移动到屏幕上的确切点(以允许输入显示或其他任何内容)

let coords = .. the coords of the town, house etc
// for example, if you let someone tap on the map, something like...
let coords = map.convert(g.location(in: map), toCoordinateFrom: map)

// we'll need the W/H of the map on the device:

let W = self.map.bounds.width
let H = self.map.bounds.height

// here's the formula to tidily and safely move/zoom
// to center a coords on the screen
let thatRegion = MKCoordinateRegion(
    center: coords,
    latitudinalMeters: 5000 * Double((H/W)),
    longitudinalMeters: 5000)

MKMapView.animate(withDuration: 2, animations: { [weak self] in

    self?.map.region = thatRegion

}, completion: {completed in
    print("part 1 done")

    // so now the coords is centered. but we want to move it
    // so that we can see something else we're adding to the
    // screen on top, such as an input display

...这是第一部分。

现在您想继续为移动设置动画以将其从您的用户体验中移开:

    MKMapView.animate(withDuration: 2, animations: { [weak self] in
        guard let self = self else { return }

        // in this example, we'll move the point,
        // to the top-left of the screen, just below the notch:

        let UP = H/2 - 20
        let LEFT = W/4

        // here's the exact formula for moving
        // the center of the map a certain amount UP/LEFT:

        self.map.setVisibleMapRect(self.map.visibleMapRect,
           edgePadding: UIEdgeInsets(
             top: -UP, left: -LEFT, bottom: UP, right: LEFT),
           animated: true)

    }, completion: {completed in
        print("part 2 done")
    })

})

总是这样。

另外,请记住不幸的是 MapKit 本质上是草率的。简单地说,不可能将一个地理点绝对定位在屏幕的中心;总是有一点变化。 (以一种或另一种方式说奇数个像素。)这就是 MapKit 的工作方式。此外,如果纹理数据仍在加载,动画(如上面的两个)可能会被抛弃。