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

Ios 如何在swift中访问闭包内的注释,ios,xcode,swift,parse-platform,closures,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: NSStr

我已从类中创建了自定义注释:

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查询获取一组坐标:
findobjectsinbackgroundithblock
,它收集闭包内的坐标。然后我用它们在地图上的坐标

       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
    }
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

哪个无法访问userAnnotation,因为它位于闭包内?有人有什么想法吗。我对Swift和闭包等还是有点陌生。

问题实际上与闭包无关

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

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

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

这可能会编译,甚至可能看起来“工作”,但它不可靠,这里不推荐

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


viewForAnnotation
delegate方法已经提供了通过
annotation
参数调用它的注释的引用

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


因为所有注释都将调用委托方法,所以您只需要有一种方法来区分注释

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

一个简单的方法就是添加一个布尔属性,比如
isUserAnnotation
。仅针对
用户注释将其设置为
true
,并在
注释视图中根据
isUserAnnotation
的值设置
pinColor

例如:

  • 将属性添加到注释类:

    var subtitle : NSString!
    var isUserAnnotation : Bool  // <-- new property
    
  • 创建
    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.
    
  • viewForAnnotation
    中,根据从传递到方法中的
    annotation
    对象获得的
    isUserAnnotation
    值设置
    pinColor

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

  • 谢谢,这是一个很好的回答。很明显,我对每件事都还不熟悉,所以要经历一个巨大的学习过程。谢谢你把事情处理得这么好。