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

Swift Annotation Not Placed on MapView because viewForAnnotation not called

我正在开发一个应用程序,它可以在用户当前位置放置图钉,也可以根据用户的位置输入来放置图钉。当前位置注释放置得很好,但是当尝试放置用户输入的坐标时,注释没有放置。我已经使用 map.addAnnotation(annotation) 正确添加了注释,其中 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
}

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

    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
}

我认为没有必要使用这个 viewForAnnotation function.Simply 您可以通过给注释提供坐标来显示注释,然后通过 map.addAnnotation(annotation) 函数将其放入地图中。

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

不幸的是,您的代码运行良好;希望你没有忘记打电话给 add:

override func viewDidLoad() {
    super.viewDidLoad()

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

结果如下:

首先,

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

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

  1. Returns the view associated with the specified annotation object, i.e. The annotation view to display for the specified annotation or nil if you want to display a standard annotation view.`

  2. If you do not implement this method, or if you return nil from your implementation for annotations other than the user location annotation, the map view uses a standard pin annotation view.`

在这里查看-

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

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

func add(newLocation location_one:[String:Any])来自后台队列,里面调用了addAnnotatinon()方法。

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

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. The addAnnotation method is called from the main thread
  2. viewForAnnoation method - you use it to provide customisation to the default pin of the annotation.