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

0sgqnhkj  于 2023-04-28  发布在  Swift
关注(0)|答案(3)|浏览(106)

我正在开发一个应用程序,它可以在用户当前的位置放置一个大头针,并根据用户对位置的输入来放置大头针。当前位置注解被放置得很好,但是当尝试放置用户的输入坐标时,注解未被放置。
我已经使用map.addAnnotation(annotation)为which annotation正确地添加了注解。坐标(纽约)是CLLocationCoordinate2D(latitude: 40.713054, longitude: -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类型。如上所述,注解。coordinate(对于纽约)产生CLLocationCoordinate2D(latitude: 40.713054, longitude: -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
}
yi0zb3m4

yi0zb3m41#

首先
func mapView(_ map: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView?
这是一个委托方法,不用于设置注解,它只是
1.返回与指定注解对象关联的视图,即e.要为指定的注解显示的注解视图,或者如果要显示标准注解视图,则为nil。”
1.如果您没有实现这个方法,或者如果您的实现对于用户位置注解以外的注解返回nil,那么Map视图将使用标准的pin注解视图。”
在这里检查一下-
https://developer.apple.com/reference/mapkit/mkmapviewdelegate/1452045-mapview
addAnnotation()方法足以添加默认的pin注解。它可能没有被调用,因为您可能已经调用了
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.从主线程调用addAnnotation方法

  1. viewForAnnoation方法-您可以使用它来提供对注解默认pin的自定义。
cclgggtu

cclgggtu2#

我认为没有必要使用这个viewForAnnotation函数。简单地说,你可以通过给出注解的坐标来显示注解,并通过map.addAnnotation(annotation)函数将其放入Map中。

xzv2uavs

xzv2uavs3#

首先,不要在viewForAnnotation方法中调用map.showAnnotations,因为每次MapKit决定绘制注解视图时都会调用它--所以如果有多个可用的注解,Map将讨厌地重新定位自己,这可能导致无限循环(不确定最后一个,但我可以想到这种情况可能发生的情况)。您应该只在用户请求时调用map.showAnnotations(例如。例如,按钮按压或其他选择),以使Map以那些注解为中心。
不幸的是,你的代码工作得很好;希望你没有忘记调用add

override func viewDidLoad() {
    super.viewDidLoad()

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

结果如下:

相关问题