путаница в viewForAnnotation и итеративная настройка pinColor

Цель состоит в том, чтобы настроить цвета выводов для некоторых значений, хранящихся в структурном массиве.

Для некоторой помощи здесь я реализовал следующий метод делегата 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
}

Внутри моего цикла for внутри ViewController я вызываю это следующим образом, но я ничего не делаю с возвращением.

        // previous to this I setup some Titles and Subtitle which work fine
        self.theMapView.addAnnotation(myAnnotation)
        // Call to my mapview   
        mapView(theMapView, viewForAnnotation: myAnnotation)

Я ничего не делаю с возвратом Pinview - не думал, что мне нужно, но все контакты на этом этапе закрашиваются красным при использовании кода переключателя. По сути, я должен что-то здесь упустить.

7-8-14 Обновления для решения проблем с исправленным кодом в соответствии с большой помощью / обучением Анны. 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

  }
}

Пересмотренный mapView - теперь с использованием новой 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

В viewDidLoad настройки и цикл 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

Отладочный вывод показывает, что цикл For выполняется до завершения, как и ожидалось, для создания myCustomPinAnnotation's, прежде чем пользовательский viewForAnnotation в mapView будет выполнен сам по себе. Когда я перемещаю карту в области за пределами непосредственного вида, я отмечаю, что viewForAnnotation в mapView вызывается по мере необходимости, и я вижу, что мой переключатель работает соответствующим образом, но цвета выводов не всегда правильные. Все контакты в исходной карте отображения правильны каждый раз, поэтому я остановился на этих внешних областях, чтобы понять, почему они отключены.

Ответы на вопрос(1)

Ваш ответ на вопрос