Swift Annotation未放置在MapView上,因为未调用viewForAnnotation

时间:2017-01-31 02:36:40

标签: swift annotations mkmapview

我正在开发一个应用程序,它将一个引脚放在用户当前位置,并根据用户输入的位置放置引脚。当前位置注释正好放置,但是当尝试放置用户的输入坐标时,不会放置注释。我已经使用map.addAnnotation(注释)正确添加了注释,其中annotation.coordinate(对于纽约)是CLLocationCoordinate2D(纬度:40.713054,经度:-74.007227999999998)。我发现没有调用viewForAnnotation方法,我认为这就是没有放置注释的原因(打印注释结果为空)。我有一个请求输入坐标的测试应用程序,它可以放置注释。同样在测试应用程序中,在viewForPrints中打印注释值。

下面我粘贴了一些我认为与此问题相关的代码。如果您需要更多,请发表评论。

import UIKit
import MapKit
import CoreLocation
class MapVC: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {



@IBOutlet weak var map: MKMapView!

override func viewDidLoad() {
    super.viewDidLoad()
    map.delegate = self
}

下面的这个函数获取另一个类的值,并将坐标转换为CLLocationCoordinate2D类型。如上所述,annotation.coordinate(对于纽约)产生CLLocationCoordinate2D(纬度:40.713054,经度:-74.007227999999998),因此add用于保存坐标。

    func add(newLocation location_one:[String:Any]) {
        let momentaryLat = (location_one["latitude"] as! NSString).doubleValue
        let momentaryLong = (location_one["longitude"] as! NSString).doubleValue

        let annotation = MKPointAnnotation()
        annotation.title = location_one["title"] as? String
        annotation.coordinate = CLLocationCoordinate2D(latitude: momentaryLat as CLLocationDegrees, longitude: momentaryLong as CLLocationDegrees)



        map.addAnnotation(annotation) //not sure if this adds the annotation!

        self.map.centerCoordinate = annotation.coordinate
    }


func mapView(_ map: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {

    if (annotation is MKUserLocation) {
        return nil
    }

    let identifier = "pinAnnotation"
    var annotationView = map.dequeueReusableAnnotationView(withIdentifier: identifier) as? MKPinAnnotationView

    if annotationView == nil {
        annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
        annotationView?.canShowCallout = true

    } else {
        annotationView?.annotation = annotation

    }
    map.showAnnotations(map.annotations, animated: true)
    return annotationView
}

3 个答案:

答案 0 :(得分:3)

首先,

func mapView(_ map: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView?

这是一个委托方法,不用于设置注释, 它只是

  
      
  1. 返回与指定注释对象关联的视图,即要为指定注释显示的注释视图,如果要显示标准注释视图,则返回nil。

  2.   
  3. 如果您没有实现此方法,或者您从实现中返回除用户位置注释以外的注释的nil,则地图视图使用标准的图钉注释视图。

  4.   

在这里查看 -

https://developer.apple.com/reference/mapkit/mkmapviewdelegate/1452045-mapview

addAnnotation()方法足以添加默认的引脚注释。它可能没有被调用,因为你可能已经调用了

来自后台队列的

func add(newLocation location_one:[String:Any]),后面调用addAnnotatinon()方法。

如果你在后台队列中调用另一个控制器中的add方法,可能是一些完成处理程序,那么你需要明确地执行它并在主线程上调用add annotation方法

DispatchQueue.main.async {
    self.map.addAnnotation(annotation) //Yes!! This method adds the annotations
}

出于调试目的,将控制器更改为此,甚至删除代理,然后您也可以看到注释。

import UIKit
import MapKit

class ViewController:  UIViewController{

@IBOutlet weak var map: MKMapView!

      override func viewDidLoad() {
          super.viewDidLoad()
          let annotation = MKPointAnnotation()
          annotation.title = "Test Location"
          annotation.coordinate = CLLocationCoordinate2D(latitude: 40.71304, longitude: -74.0072)
          self.map.addAnnotation(annotation)
      }
}

所以确保 -

  
      
  1. 从主线程
  2. 调用addAnnotation方法   
  3. viewForAnnoation方法 - 您可以使用它来为注释的默认引脚提供自定义。
  4.   

答案 1 :(得分:0)

我认为不需要使用这个viewForAnnotation函数。只需通过给出注释的坐标并通过map.addAnnotation(annotation)函数将其放入地图中来显示注释。

答案 2 :(得分:0)

首先,你不要在map.showAnnotations方法中调用viewForAnnotation,因为每次MapKit决定绘制注释视图时都会调用它 - 所以如果有多个注释可用,地图会烦人地重新定位自己,这可能导致无限循环(不确定最后一个,但我可以想到可能发生这种情况的情况)。您只应在用户请求(例如按下按钮或其他选择)时调用map.showAnnotations,以使地图围绕这些注释。

不幸的是,你的代码完美无缺;希望您不要忘记致电add

override func viewDidLoad() {
    super.viewDidLoad()

    let loc = ["latitude": "40.713054", "longitude":"-74.00722", "title": "nyc"]
    add(newLocation: loc)
}

结果如下: enter image description here