Swift MapView未向Map添加注释



因此,对于我的mapView,我通过全局数组将经度和纬度传递给另一个VC来接收坐标,例如:

将纬度和经度添加到阵列中:

var location_one: [String: Any] = ["title": eventName, "latitude": latitude, "longitude": longitude]
locations.append(location_one)
if let tbc = self.tabBarReference {
if let map = tbc.viewControllers?[1] as? MapVC {
map.loadViewIfNeeded()
map.add(newLocation:location_one)
}
}

在MapViewVC:上接收坐标

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)
//        self.map.centerCoordinate = annotation.coordinate
}

视图注释代码:

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

let identifier = "pinAnnotation"
var annotationView = map.dequeueReusableAnnotationView(withIdentifier: identifier) as? MKPinAnnotationView
if annotationView == nil {
annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
annotationView?.canShowCallout = true
}
annotationView?.annotation = annotation
return annotationView
}

坐标正在正确传输,并且正在调用func-add(使用break语句进行验证),但是当我转到模拟器中的MapView时,注释没有被放置。我不知道发生了什么,因为这在我测试的另一个应用程序中运行正常,但不知道是什么导致了它的混乱。

我还有一个代码,可以找到用户的当前位置,并在此基础上放置一个pin。。。也许这会打乱添加坐标的代码?

我建议仔细检查momentaryLatmomentaryLong的数值,因为可能由于解析问题,它们不是你想象的那样(例如,在大西洋中,确保它们不是0.0!)。在您将其转换为NSString并从中提取双倍值之前,我们必须先了解location_one["latitude"]的值是什么。把它分解成不同的步骤,问题很可能会突然出现在你身上。


您的viewFor看起来不错。不相关,我建议将annotationView?.annotation = annotation放在前面的if语句的else子句中(如果您刚刚使用相同的annotation创建了MKPinAnnotationView,则无需设置annotation……只有在重用注释视图时才需要这样做)。我通常也会检查以确保注释不是MKUserLocation,因为我们通常让地图视图为我们呈现它

func mapView(_ map: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if annotation is MKUserLocation { return nil }   // let the OS show user locations itself
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
}
return annotationView
}

但这两个观察结果都与您的注释缺失问题无关。


记住,只有当地图的一个或多个annotationscoordinate位于地图的可见部分内时,才会调用viewForAnnotation(或Swift 3中的viewFor)方法,因此它得出结论,需要渲染相关的注释视图。因此,人们不会期望它被调用,直到(a)地图试图绘制自己,以及(b)一个或多个注释的坐标在地图的可见部分内(或附近)。

例如,如果向地图对象添加了100个注释,其中只有10个位于地图的可见部分内,则将仅创建10个注释视图。如果你滚动地图,使5个从视图中掉出来,7个滚动到视图中,它会调用viewForAnnotation 7次,每个新可见的注释一次。viewForAnnotation可能会成功地将滚动出视图的5个注释视图出列/重用,并且只会为另外两个视图创建新的注释视图。(这比这更复杂,但这是基本的想法。)

这类似于表/集合视图,其中仅为可见单元格创建单元格。因此,如果模型中有100个对象,但表中只有12行可见,则只能创建12个单元格。当一行从视图中滚动出来时,它就可以出列/重新用于未来滚动到视图中的行。这是一种常见的模式,您将在整个iOS中看到,在iOS中,计算成本高昂的视图对象只在需要时创建,并在可能的情况下重用。

最新更新