如何在 swift 中访问闭包内的注释



>我从一个类创建了一个自定义注释:

import UIKit
import MapKit
class annotationCustom: NSObject, MKAnnotation {
    var coordinate : CLLocationCoordinate2D
    var title : NSString!
    var subtitle : NSString!
    init(coordinate: CLLocationCoordinate2D, title: NSString!, subtitle: NSString!){
        self.coordinate = coordinate
        self.title = title
        self.subtitle = subtitle
    }
}

然后,我使用 parses 查询获取一组坐标:findObjectsInBackgroundWithBlock 它收集闭包内的坐标。然后,我在地图上使用它们的坐标。

       var otherUsersLat = coord.latitude as Double
       var otherUsersLong = coord.longitude as Double
                    //Other Users coords.
           var location = CLLocation(latitude: otherUsersLat, longitude: otherUsersLong)
           let latitude:CLLocationDegrees = location.coordinate.latitude
           let longitude:CLLocationDegrees = location.coordinate.longitude
           let latDelta:CLLocationDegrees = 0.003
           let lonDelta:CLLocationDegrees = 0.003
           let span:MKCoordinateSpan = MKCoordinateSpanMake(latDelta, lonDelta)
           let finalLocation:CLLocationCoordinate2D = CLLocationCoordinate2DMake(latitude, longitude)
           let region:MKCoordinateRegion = MKCoordinateRegionMake(finalLocation, span)
                    self.myMap.setRegion(region, animated: true)

然后,我在地图上设置了注释。

for name in names {
                        if name == PFUser.currentUser().username {
                             var userAnnotation = annotationCustom(coordinate: finalLocation, title: "You are here", subtitle: "Hey")
                            self.myMap.addAnnotation(userAnnotation)
                        } else {
                            var otherAnnotation = annotationCustom(coordinate: finalLocation, title: name, subtitle: "Hey")
                            self.myMap.addAnnotation(otherAnnotation)
                        }

我创建了两个注释,一个用于当前用户,一个用于其他用户。我正在尝试更改仅userAnnotation的属性.

我尝试使用该方法:

 func mapView(mapView: MKMapView!, viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! {
        var view = MKPinAnnotationView(annotation: userAnnotation, reuseIdentifier: "pin")
        view.pinColor = MKPinAnnotationColor.Green
        return view
    }

哪个无法访问用户注释,因为它在闭包内部?有没有人有任何想法。我仍然对 Swift 和关闭等有点陌生。

这个问题实际上与闭包无关。

它更多地与变量作用域以及如何在委托方法中处理外部数据有关。

userAnnotation变量在for循环内的if块中本地声明,而循环恰好在闭包内。 userAnnotation变量实际上只能在if块中使用该名称进行访问。 这就是它的范围。

您可以将userAnnotation声明移动到更高级别(例如在视图控制器的类级别),以便它在闭包和委托方法内的if块中可见。

这可能会编译,甚至可能看起来"有效",但它不可靠,不建议在这里使用。

不保证在addAnnotation后立即调用 viewForAnnotation 委托方法,也不保证每个批注只调用一次。 确保外部变量的值与调用委托方法的注释同步是非常困难或不可能的。


viewForAnnotation 委托方法已提供对通过 annotation 参数调用它的批注的引用。

viewForAnnotation中的代码应仅使用传递给方法的annotation参数的属性来确定视图特征。


由于将为所有批注调用委托方法,因此您只需要有一种方法来区分批注。

您可以使用title并检查它是否等于"您在这里",但这不是很灵活。 更好的方法是向自定义批注类添加另一个属性,该属性专门帮助您确定批注是否为"用户"批注。

一个简单的方法是添加一个布尔属性,如 isUserAnnotation . 将其设置为仅true userAnnotation,并在viewForAnnotation中,根据isUserAnnotation的值设置pinColor

例如:

  1. 将属性添加到注释类:

    var subtitle : NSString!
    var isUserAnnotation : Bool  // <-- new property
    
  2. 默认属性在 init 方法中false

    self.subtitle = subtitle
    self.isUserAnnotation = false
    
  3. 创建 userAnnotation 时,将新属性设置为 true

    var userAnnotation = annotationCustom(coordinate: finalLocation, title: "You are here", subtitle: "Hey")
    userAnnotation.isUserAnnotation = true
    self.myMap.addAnnotation(userAnnotation)
    //For OtherAnnotation, you could set the property to false
    //or do nothing since it's defaulted to false in the init method.
    
  4. viewForAnnotation 中,根据从传递给方法annotation对象获取的isUserAnnotation的值设置pinColor

    var view = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "pin")
    if let ac = annotation as? annotationCustom {
        if ac.isUserAnnotation {
            view.pinColor = MKPinAnnotationColor.Green
        }
        else {
            view.pinColor = MKPinAnnotationColor.Red
        }
    }
    return view
    

最新更新