【问题标题】:How to offset MKMapView to put coordinates under specified point如何偏移 MKMapView 以将坐标放在指定点下
【发布时间】:2017-08-23 05:43:12
【问题描述】:

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

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

我想要的是让用户能够点击他们在第二个 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 的中心?

【问题讨论】:

标签: ios swift mkmapview coordinates


【解决方案1】:

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

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

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

【讨论】:

  • 您好,感谢您的建议。尽管我正在努力获得偏移地图的距离,但这似乎可以工作。我假设它会是这样的:“let offset = pinImageView.center.y - mapView.center.y”但是地图虽然更接近它应该在的位置,但仍然关闭。你知道这是否是计算偏移量的正确方法吗?
  • 这将取决于你如何布置它,但理论上你是在正确的轨道上。看起来您在上面的屏幕截图中描绘的半透明视图可以用来计算偏移量,只需使用它的高度。
【解决方案2】:

从优秀的@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 的工作方式。此外,如果纹理数据仍在加载,动画(例如上面的两个)可能会被丢弃。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-01-11
    • 2022-06-15
    • 2021-08-04
    • 2011-12-20
    • 2021-08-07
    • 2018-06-23
    • 1970-01-01
    • 2014-10-24
    相关资源
    最近更新 更多