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

How to access an annotation inside a closure in 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
    }

}

然后我使用解析查询获取一组坐标: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
    }

哪个无法访问闭包内的 userAnnotation?有没有人有任何想法。我对 Swift 和闭包等仍然有点陌生。

这个问题实际上与闭包没有任何关系。

它与变量范围以及在委托方法中应如何处理外部数据有更多关系。

userAnnotation 变量是在 for 循环内的 if 块中局部声明的,所有这些都恰好在闭包内。 userAnnotation 变量实际上只能在 if 块中使用该名称访问。这是它的范围。

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

这可能会编译,甚至可能 "work" 但它不可靠,因此不建议在此处使用。

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


viewForAnnotation 委托方法已经通过 annotation 参数提供了对其调用的注解的引用。

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


由于所有注解都会调用委托方法,所以你只需要有一种方法来区分注解。

可以 使用 title 并检查它是否等于 "You are here" 但这不是很灵活。更好的方法是在自定义注解class中再添加一个属性,专门帮助你识别该注解是否为"user"注解。

一个简单的方法就是添加一个布尔值 属性,例如 isUserAnnotation。仅对 userAnnotation 设置为 true,在 viewForAnnotation 中,根据 isUserAnnotation.

的值设置 pinColor

例如:

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

    var subtitle : NSString!
    var isUserAnnotation : Bool  // <-- new property
    
  2. init方法中默认[=​​96=]到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