【问题标题】:Failed to set maprect to show all annotations未能将 maprect 设置为显示所有注释
【发布时间】:2015-01-26 16:51:19
【问题描述】:

我有 2 个注释要显示在 mapview 上,但无法将 maprect 设置为在屏幕上显示所有注释而不需要用户缩小。

我尝试使用showAnnotations,但没有运气。任何人都能够在 Swift 和 Xcode 6.1.1 中做到这一点?

这是我的代码:

class ViewController: UIViewController, MKMapViewDelegate {


    @IBOutlet var map: MKMapView!

    override func viewDidLoad() {
        super.viewDidLoad()

        var mapView = map
        // 1
        let point1 = CLLocationCoordinate2D(latitude: 38.915565, longitude: -77.093524)
        let point2 = CLLocationCoordinate2D(latitude: 38.890693, longitude: -76.933318)

        //2
        let annotation = MKPointAnnotation()
        annotation.setCoordinate(point1)
        annotation.title = "point1"
        map.addAnnotation(annotation)

        let annotation2 = MKPointAnnotation()
        annotation2.setCoordinate(point2)
        annotation2.title = "point2"
        map.addAnnotation(annotation2)

        //3
        // option1: set maprect to cover all annotations, doesn't work
        var points = [annotation, annotation2]
        var rect = MKMapRectNull
        for p in points {
            let k = MKMapPointForCoordinate(p.coordinate)
            rect = MKMapRectUnion(rect, MKMapRectMake(k.x, k.y, 0.1, 0.1))
            println("result: x = \(rect.origin.x) y = \(rect.origin.y)")
        }

        map.setVisibleMapRect(rect, animated: true)

        // option 2: using showAnnotations, doesn't work
        //map.showAnnotations(points, animated: true)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


     }

这是我目前得到的:

这是我期望看到的:

感谢您的帮助。

【问题讨论】:

  • 你能解释一下你说showAnnotations“不起作用”的确切含义吗?发生什么了?对于 setVisibleMapRect,您可能需要应用 inset(参见 stackoverflow.com/a/22070026/467105 的示例)。此外,您已经实现了viewForAnnotation,它显示了注释的自定义图像,但在您“预期”的屏幕截图中,它显示了默认的红色引脚。为什么你会期待默认的红色图钉?
  • Anna,我对 showAnnotations 的“不起作用”的意思是它没有像预期的屏幕那样显示所有引脚。
  • 带有 showAnnotations 的代码看起来不错。如果您更喜欢 setVisibleMapRect,请添加一个插图。 在测试缩放时完全注释掉 viewForAnnotation 方法。修复缩放后,使用 viewForAnnotation 解决问题。 如果没有显示任何引脚,请确保正在调用 viewForAnnotation(确保已设置地图委托,确保图像文件存在)。
  • 安娜,如果你说“showAnnotations 看起来不错”,为什么它不起作用?你试过那个代码了吗?
  • 是的,我尝试了问题中发布的代码并且它有效。 showAnnotations 工作没有任何变化。对于 setVisibileMapRect,需要应用一个 inset,这样注释就不会完全位于屏幕边缘。

标签: swift mkmapview mkannotation mkmaprect


【解决方案1】:

我终于找到了为什么注释的大头针没有显示在屏幕的可见区域中。我认为 MapKit 框架的行为与以前的版本有些不同。由于我使用自动布局允许地图扩展到所有设备(iPhone、iPad)的整个屏幕,因此应在 mapViewDidFinishLoadingMap 中调用地图的 setVisibleMapRect 或 mapView.showAnnotations,而不是在视图控制器的 viewDidLoad 中调用

例如:

 func mapViewDidFinishLoadingMap(_ mapView: MKMapView) {
     // this is where visible maprect should be set
     mapView.showAnnotations(mapView.annotations, animated: true)  
 }

【讨论】:

  • 最好在mapViewDidFinishRenderingMapdelegate 方法中显示注释。
【解决方案2】:

我打电话时遇到了同样的问题

viewDidLoad() {
    mapView.showAnnotations(myAnnotations, animated: false)
}

但是,将调用移动到 viewDidLayoutSubviews() 似乎也可以解决问题(并不是 isInitialLoad 在 vi​​ewDidLoad 中被初始化为 true)。

viewDidLayoutSubviews() {
    if isInitialLoad {
        mapView.showAnnotations(myAnnotations, animated: false)
        isInitialLoad = false
    }
} 

将调用放在 viewDidLayoutSubviews 中的区别(我认为这是一个优势)是地图尚未实际显示,因此您的初始显示是注释定义的区域。不过好像每次地图缩放都会调用,所以需要确保只在第一次调用。

【讨论】:

    【解决方案3】:

    对我来说,在地图加载完成后使用显示注释不起作用。

    func mapViewDidFinishLoadingMap(mapView: MKMapView!) {
     // this is where visible maprect should be set
     mapView.showAnnotations(mapView.annotations, animated: true)  
    }
    

    除了显示注解之外,我还需要计算多段线来连接注解,并且地图完成加载过早触发。

    相反,我尝试了 mapViewDidFinishRenderingMap,它工作得非常好。请参见下面的示例:

    //MARK: - Show all objects after adding them on the map
    func mapViewDidFinishRenderingMap(mapView: MKMapView, fullyRendered: Bool) {
        mapView.showAnnotations(mapStages, animated: true)
    }
    

    【讨论】:

      【解决方案4】:

      你可以试试这个。 我创建了一个扩展来使用 swift 2.3 中的一些代码来显示所有注释。如果即使在最大缩放级别下也无法显示所有注释,这将不会显示所有注释。

      import MapKit
      
      extension MKMapView {
          func fitAllAnnotations() {
              var zoomRect = MKMapRectNull;
              for annotation in annotations {
                  let annotationPoint = MKMapPointForCoordinate(annotation.coordinate)
                  let pointRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 0.1, 0.1);
                  zoomRect = MKMapRectUnion(zoomRect, pointRect);
              }
              setVisibleMapRect(zoomRect, edgePadding: UIEdgeInsetsMake(20, 20, 20, 20), animated: true)
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-06-14
        • 2023-03-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多