我有以下代码,该代码旨在遍历当前苹果 map View 上的所有注释并更新其位置坐标。

for existingMarker in self.mapView.annotations {

    existingMarker.coordinate.latitude = 12.12121212
    existingMarker.coordinate.longitude = 14.312121121
}

遗憾的是,这是不允许的。有人告诉我,“坐标”是一个只能获得的属性。因此,这显然不是我要更新已经在mapView上绘制的MKAnnotation的注释位置的方式。那我该怎么做呢?具体来说,我想这样做,并使用新坐标尽快使 map “重绘”。我肯定这是有可能的,因为这似乎是一个常见的用例。

最佳答案

问题是annotationsMKAnnotation的数组。但是此协议(protocol)仅要求具有coordinate属性,但并不要求它是变量。注意协议(protocol)中没有set:

public protocol MKAnnotation : NSObjectProtocol {

    // Center latitude and longitude of the annotation view.
    // The implementation of this property must be KVO compliant.
    var coordinate: CLLocationCoordinate2D { get }

    ...
}

因此,当遍历annotationsMKMapView(定义为MKAnnotation数组)时,它不知道您的坐标是变量还是常数,并生成该警告。

但是,假设您的注释是MKPointAnnotation。在该具体注释类型中,coordinate是变量,而不是常量。因此,您可以具体说明类型。例如:
for annotation in mapView.annotations {
    if let annotation = annotation as? MKPointAnnotation {
        annotation.coordinate = CLLocationCoordinate2D(latitude: 12.12121212, longitude: 14.312121121)
    }
}

或者
mapView.annotations
    .compactMap { $0 as? MKPointAnnotation }
    .forEach { existingMarker in
        existingMarker.coordinate = CLLocationCoordinate2D(latitude: 12.12121212, longitude: 14.312121121)
}

显然,如果您定义自己的符合MKAnnotation的注释类,则显然:
  • coordinate定义为变量,而不是常量;和
  • 确保其为dynamic

  • 因此:
    class MyAnnotation: NSObject, MKAnnotation {
        dynamic var coordinate: CLLocationCoordinate2D
        dynamic var title: String?
        dynamic var subtitle: String?
    
        // other properties unique to your annotation here
    
        init(coordinate: CLLocationCoordinate2D, title: String? = nil, subtitle: String? = nil) {
            self.coordinate = coordinate
            self.title = title
            self.subtitle = subtitle
    
            super.init()
        }
    }
    

    然后该模式与上述相同,除了引用您的类,例如:
    mapView.annotations
        .compactMap { $0 as? MyAnnotation }
        .forEach { existingMarker in
            existingMarker.coordinate = CLLocationCoordinate2D(latitude: 12.12121212, longitude: 14.312121121)
    }
    

    10-08 16:23