viewForAnnotation Verwirrung und Anpassen der PinColor iterativ

Das Ziel ist es, die Stiftfarben für einige in einem Strukturarray gespeicherte Werte anzupassen.

Als Hilfe hier habe ich die folgende viewForAnnotation-Delegate-Methode implementiert, und das funktioniert hervorragend, wenn diese Delegate-Methode in einer Schleife iterativ aufgerufen wird, die auf der Größe meines Strukturdaten-Arrays basiert. So funktioniert es, wenn ich alle Stifte auf eine Farbe einstellen möchte, zum Beispiel lila (das ist die kommentierte Zeile im Code unten).

Das Problem ist, wenn ich einen Schalter einsetze, um die Farbe basierend auf einem Wert in meinem Array festzulegen, der diesen Code durchläuft, aber keinen der Fallwerte beachtet, um eine alternative Farbe festzulegen, und alles geht an einen roten Stift (anscheinend) der Standard). Ich habe den Status ausgedruckt und getestet, um zu wissen, dass er in den Schalter gelangt und PinColor entsprechend einstellt, aber sie scheinen nicht zu haften.

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
}

In meiner for-Schleife im ViewController rufe ich dies wie folgt auf, aber ich mache nichts mit der Rückgabe.

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

Ich mache nichts mit der Rückgabe von Pinview - hätte nicht gedacht, dass ich das tun müsste, aber alle Pins werden an dieser Stelle rot gezeichnet, wenn der Schaltercode verwendet wird. Grundsätzlich muss mir hier etwas fehlen.

7-8-14 Aktualisierungen zur Behebung von Problemen mit überarbeitetem Code gemäß Annas hervorragender Hilfe / Anleitung. TKS!

Es funktioniert fast. Alle Pins in der Karte haben die richtigen Farben, aber diejenigen außerhalb der unmittelbaren Anzeige sind manchmal falsch. Das Posten des gesamten Codes, der hier enthalten ist, kann anderen helfen, da dies eine sehr häufige Frage zur Durchführung benutzerdefinierter Arbeiten in Maps zu sein scheint.

Eine benutzerdefinierte Klasse, die vorgeschlagen wird, um andere Variablen in einer benutzerdefinierten Annotation aufzunehmen - in diesem Fall den Statuswert aus meiner Datenstruktur 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

  }
}

Die überarbeitete Kartenansicht - verwendet jetzt die neue CustomMapPinAnnotation, die an sie übergeben wird:

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

In viewDidLoad die Setup- und For-Schleife, um die Anmerkungen einzurichten

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

Die Debug-Ausgabe zeigt, dass die For-Schleife wie erwartet vollständig ausgeführt wird, um die myCustomPinAnnotation zu erstellen, bevor die benutzerdefinierte viewForAnnotation in mapView selbstständig ausgeführt wird. Wenn ich die Karte in Bereiche außerhalb der unmittelbaren Ansicht verschiebe, bemerke ich, dass viewForAnnotation in mapView bei Bedarf aufgerufen wird und mein Schalter entsprechend ausgeführt wird, aber die Stiftfarben nicht immer korrekt sind. Alle Stifte in der anfänglichen Anzeigekarte sind jedes Mal korrekt, also sind es diese äußeren Regionen, auf denen ich momentan festhalte, warum sie ausgeschaltet sind.

Antworten auf die Frage(1)

Ihre Antwort auf die Frage