Ios viewForAnnotation混淆和反复定制pinColor

Ios viewForAnnotation混淆和反复定制pinColor,ios,swift,mkannotationview,Ios,Swift,Mkannotationview,目标是根据存储在结构数组中的某些值自定义管脚颜色 根据这里的一些帮助,我实现了下面的viewForAnnotation委托方法,根据我的结构数据数组的大小在循环中迭代调用这个委托方法非常有效。因此,如果我想将所有管脚设置为一种颜色,例如紫色(这是下面代码中的注释行),它就可以工作 问题是,当我输入一个开关以根据数组中的值设置颜色时,它会通过此代码,但不考虑任何大小写值以将其设置为备用颜色,所有内容都会转到一个红色引脚(似乎是默认值)。我已经打印出了状态,并进行了调试,知道它正在进入开关,并相应地

目标是根据存储在结构数组中的某些值自定义管脚颜色

根据这里的一些帮助,我实现了下面的viewForAnnotation委托方法,根据我的结构数据数组的大小在循环中迭代调用这个委托方法非常有效。因此,如果我想将所有管脚设置为一种颜色,例如紫色(这是下面代码中的注释行),它就可以工作

问题是,当我输入一个开关以根据数组中的值设置颜色时,它会通过此代码,但不考虑任何大小写值以将其设置为备用颜色,所有内容都会转到一个红色引脚(似乎是默认值)。我已经打印出了状态,并进行了调试,知道它正在进入开关,并相应地设置了pinColor,但它们似乎没有粘住

func mapView(aMapView: MKMapView!,
    viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! {

       let theindex = mystructindex  // grab the index from a global to be used below

        if annotation is MKUserLocation {
            //return nil so map view draws "blue dot" for standard user location
            return nil
        }

        let reuseId = "pin"
        var pinView = aMapView.dequeueReusableAnnotationViewWithIdentifier(reuseId) as? MKPinAnnotationView

        if pinView == nil {
            //println("Pinview was nil")
            pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
            pinView!.canShowCallout = true
            pinView!.animatesDrop = true

            // Preventive if to keep this from being called beyond my arrays index value as the delegate getting called beyond the for loop for some unknown reason

            if (theindex < MySupplierData.count) {

                // Set the pin color based on the status value in MySupplierData structure array
                switch MySupplierData[mystructindex].status  {

                case 0,1:
                    println("Case 0 or 1 - setting to Red")
                    pinView!.pinColor = .Red  // Needs help, show red pin
                case 2:
                    println("Case 2 - Setting to Green")
                    pinView!.pinColor = .Green  // Looking Good 
                case 3:
                    println("Case 3 - Setting to Purple")
                    pinView!.pinColor = .Purple  // Could use a follow-up
                default:
                    println("Case default - Should Never Happen")
                    break;

                }   // end switch
            } // end if

            // pinView!.pinColor = .Purple  // This works fine without the switch and respects any color I set it to.
        }
        else {
            pinView!.annotation = annotation
        }

        return pinView
}
我没有对返回的Pinview做任何事情-我不认为我需要这样做,但是当使用开关代码时,所有的pin在这一点上都被画成红色。从根本上说,我肯定错过了什么


7-8-14根据Anna的“伟大帮助/指导”更新代码以解决问题。TKS

它几乎可以工作,地图上所有的图钉都有正确的颜色,但在地图外的图钉除外 即时显示有时是错误的。在这里发布所有涉及的代码,因为它可能会帮助其他人 因为这似乎是关于如何在地图中进行自定义工作的一个非常常见的问题

建议使用自定义类在自定义注释中保存其他变量—在本例中,状态值来自我的数据结构MySupplierData

class CustomMapPinAnnotation : NSObject, MKAnnotation {
  var coordinate: CLLocationCoordinate2D
  var title: String
  var subtitle: String
  var status: Int

  init(coordinate: CLLocationCoordinate2D, title: String, subtitle: String, status: Int) {
    self.coordinate = coordinate
    self.title = title
    self.subtitle = subtitle
    self.status = status

  }
}
修订后的地图视图-现在使用传递给它的新CustomMapPinAnnotation:

func mapView(aMapView: MKMapView!,
    viewForAnnotation annotation: CustomMapPinAnnotation!) -> MKAnnotationView! {

        let reuseId = "pin"          
        var pinView = aMapView.dequeueReusableAnnotationViewWithIdentifier(reuseId) as? MKPinAnnotationView

        if pinView == nil {
            //println("Pinview was nil")
            pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
            pinView!.canShowCallout = true
            pinView!.animatesDrop = true

            // Code to catch my custom CustomMapPinAnnotation so we can check the status and set the color               
            if annotation.isKindOfClass(CustomMapPinAnnotation)
            {
                println("FOUND OUR CustomMapPinAnnotation CLASS IN mapView")
                println(" Custom Title = \(annotation.title)")
                println(" Custom status passed = \(annotation.status)")
                switch annotation.status {

                case 0,1:
                    println("Case 0 or 1 - Setting to Red")
                    pinView!.pinColor = .Red
                case 2:
                    println("Case 2 - Setting to Green")
                    pinView!.pinColor = .Green
                case 3:
                    println("Case 3 - Setting to Purple")
                    pinView!.pinColor = .Purple 
                default:
                    println("Case default - Should Never Happen")
                    break;
                }  // switch   
            }  // if     
        }
        else {
            pinView!.annotation = annotation
        }
        return pinView
} //func mapView
在VIEWDID中,加载设置和For循环以设置注释

override func viewDidLoad() {
    super.viewDidLoad()

    // setup the region and Span 
    var theSpan:MKCoordinateSpan = MKCoordinateSpanMake(latDelta, longDelta)

    // Set the region to the the first element of the structure array.
    var theRegion:MKCoordinateRegion = MKCoordinateRegionMake(CLLocationCoordinate2DMake(MySupplierData[0].latitude, MySupplierData[0].longitude), theSpan)

    // This set the Map Type (Standard, Satellite, Hybrid)
    self.theMapView.mapType = MKMapType.Standard

    // Now loop through the structure data from 1 top the end of the structure to map the data

    var mytitle: String = ""
    var mysubtitle: String = ""
    var myCustomPinAnnotation: CustomMapPinAnnotation

    for mystructindex = 0; mystructindex < MySupplierData.count; ++mystructindex {           
        println("INSIDE SUPPLIER LOOP INDEX = \(mystructindex)" )

        switch MySupplierData[mystructindex].status {
        case 0:
            mytitle =  "(Red) " + MySupplierData[mystructindex].company
        case 1:
            mytitle = "(Red) " + MySupplierData[mystructindex].company
        case 2:
            mytitle = "(Geeen) " + MySupplierData[mystructindex].company
        case 3:
            mytitle = "(Purple) " + MySupplierData[mystructindex].company
        default:
            mytitle = "? " + MySupplierData[mystructindex].company

        }    
        mysubtitle = MySupplierData[mystructindex].subtitle

         // Create the Custom Annotations with my added status code   
        myCustomPinAnnotation = CustomMapPinAnnotation(
            coordinate: CLLocationCoordinate2DMake(MySupplierData[mystructindex].latitude,MySupplierData[mystructindex].longitude),
            title: mytitle,        // custom title
            subtitle: mysubtitle,  // custom subtitle
            status: MySupplierData[mystructindex].status)  // status that will drive pin color

        // put this annotation in the view.
        self.theMapView.addAnnotation(myCustomPinAnnotation)
    }  // For

    // This line brings up the display with the specific region in mind, otherwise it seems to default to a US Map.
    self.theMapView.setRegion(theRegion, animated: true)

}  // viewDidLoad
override func viewDidLoad(){
super.viewDidLoad()
//设置区域和范围
变量范围:MKCoordinateSpan=MKCoordinateSpanMake(latDelta,longDelta)
//将区域设置为结构数组的第一个元素。
区域变量:MKCoordinateRegion=MKCoordinateRegionMake(CLLocationCoordinate2DMake(我的供应商数据[0]。纬度,我的供应商数据[0]。经度),跨度)
//此设置地图类型(标准、卫星、混合)
self.theMapView.mapType=MKMapType.Standard
//现在,从结构的顶端1循环结构数据,以映射数据
var mytitle:String=“”
var mysubtitle:String=“”
var myCustomPinAnnotation:CustomMapPinAnnotation
对于mystructindex=0;mystructindex
调试输出显示For循环按预期执行到完成,以在mapView中的自定义viewForAnnotation获取之前创建myCustomPinAnnotation 在内部自行执行。当我将地图移动到即时视图之外的区域时,我注意到会根据需要调用mapView中的viewForAnnotation 我看到我的开关执行相应的,但引脚颜色并不总是正确的。初始显示图中的所有管脚每次都正确,因此
我目前一直在关注这些外部区域,不知道它们为什么会关闭。

首先,代码应该而不是直接调用
视图进行注释。
删除
addAnnotation
行之后对
viewForAnnotation
的显式调用

viewForAnnotation
是一种委托方法,地图视图将在需要显示注释时自动调用它。如果没有自动调用,请确保地图视图的
delegate
属性已设置(例如设置为
self


Second(也是真正的问题)是,代码假设在添加每个注释之后,
viewForAnnotation
委托方法只会被调用一次

事实并非如此,也不能保证。地图视图在需要显示注释时将调用
viewForAnnotation
,对于同一注释可以多次调用,或者在实际添加注释后很长时间(例如,在用户平移或缩放地图并且注释进入视图后)调用

有关更多详细信息和其他答案(包括示例代码)的相关链接,请参见

基本上,您必须使用注释对象本身存储影响注释视图的属性,并从传递到
viewForAnnotation
annotation
参数中检索这些属性


我的建议
override func viewDidLoad() {
    super.viewDidLoad()

    // setup the region and Span 
    var theSpan:MKCoordinateSpan = MKCoordinateSpanMake(latDelta, longDelta)

    // Set the region to the the first element of the structure array.
    var theRegion:MKCoordinateRegion = MKCoordinateRegionMake(CLLocationCoordinate2DMake(MySupplierData[0].latitude, MySupplierData[0].longitude), theSpan)

    // This set the Map Type (Standard, Satellite, Hybrid)
    self.theMapView.mapType = MKMapType.Standard

    // Now loop through the structure data from 1 top the end of the structure to map the data

    var mytitle: String = ""
    var mysubtitle: String = ""
    var myCustomPinAnnotation: CustomMapPinAnnotation

    for mystructindex = 0; mystructindex < MySupplierData.count; ++mystructindex {           
        println("INSIDE SUPPLIER LOOP INDEX = \(mystructindex)" )

        switch MySupplierData[mystructindex].status {
        case 0:
            mytitle =  "(Red) " + MySupplierData[mystructindex].company
        case 1:
            mytitle = "(Red) " + MySupplierData[mystructindex].company
        case 2:
            mytitle = "(Geeen) " + MySupplierData[mystructindex].company
        case 3:
            mytitle = "(Purple) " + MySupplierData[mystructindex].company
        default:
            mytitle = "? " + MySupplierData[mystructindex].company

        }    
        mysubtitle = MySupplierData[mystructindex].subtitle

         // Create the Custom Annotations with my added status code   
        myCustomPinAnnotation = CustomMapPinAnnotation(
            coordinate: CLLocationCoordinate2DMake(MySupplierData[mystructindex].latitude,MySupplierData[mystructindex].longitude),
            title: mytitle,        // custom title
            subtitle: mysubtitle,  // custom subtitle
            status: MySupplierData[mystructindex].status)  // status that will drive pin color

        // put this annotation in the view.
        self.theMapView.addAnnotation(myCustomPinAnnotation)
    }  // For

    // This line brings up the display with the specific region in mind, otherwise it seems to default to a US Map.
    self.theMapView.setRegion(theRegion, animated: true)

}  // viewDidLoad