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

时间:2015-01-06 21:16:13

标签: ios xcode swift parse-platform closures

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

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 query获取一组坐标: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和闭包等有点新鲜。

1 个答案:

答案 0 :(得分:0)

问题与闭包没有任何关系。

它更多地涉及变量范围以及如何在委托方法中处理外部数据。

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

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

这可能会编译,甚至可能看起来“有效”,但它不可靠,不推荐在这里。

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

<小时/> viewForAnnotation委托方法已经通过annotation参数提供了对其调用的注释的引用。

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


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

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

一种简单的方法是添加一个布尔属性,如isUserAnnotation。仅将true设置为userAnnotation,将viewForAnnotation设置为pinColor,根据isUserAnnotation的值设置var subtitle : NSString! var isUserAnnotation : Bool // <-- new property

例如:

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

    false
  2. init方法中的属性默认为self.subtitle = subtitle self.isUserAnnotation = false

    userAnnotation
  3. 创建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.

    viewForAnnotation
  4. pinColor中,根据传递给方法的isUserAnnotation对象获取的annotation值设置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

    {{1}}