2015-09-29 7 views
15

Ich versuche, von Swift 1.2 zu Swift 2.0 zu wechseln, und ich bin am Ende der Änderungen. Zur Zeit mache ich Änderungen im MapViewController, und es gibt keinen Fehler oder eine Warnung, aber das benutzerdefinierte Bild für meinen Pin (AnnotationView) ist nicht dem Pin zugewiesen und zeigt den Standard-Pin (roter Punkt).Benutzerdefiniertes Pin-Bild in AnnotationView in iOS

Hier ist mein Code, ich hoffe, Sie mir mit etwas Spitze helfen kann, weil ich alles gut denken, aber es funktioniert immer noch nicht:

func parseJsonData(data: NSData) -> [Farmacia] { 

    let farmacias = [Farmacia]() 

    do 
    { 
     let jsonResult = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers) as? NSDictionary 

     // Parse JSON data 
     let jsonProductos = jsonResult?["farmacias"] as! [AnyObject] 

     for jsonProducto in jsonProductos { 

      let farmacia = Farmacia() 
      farmacia.id = jsonProducto["id"] as! String 
      farmacia.nombre = jsonProducto["nombre"] as! String 
      farmacia.location = jsonProducto["location"] as! String 

      let geoCoder = CLGeocoder() 
      geoCoder.geocodeAddressString(farmacia.location, completionHandler: { placemarks, error in 

       if error != nil { 
        print(error) 
        return 
       } 

       if placemarks != nil && placemarks!.count > 0 { 

        let placemark = placemarks?[0] 

        // Add Annotation 
        let annotation = MKPointAnnotation() 
        annotation.title = farmacia.nombre 
        annotation.subtitle = farmacia.id 
        annotation.coordinate = placemark!.location!.coordinate 

        self.mapView.addAnnotation(annotation) 
       } 

      }) 
     } 
    } 
    catch let parseError { 
     print(parseError) 
    } 

    return farmacias 
} 

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

    let identifier = "MyPin" 

    if annotation.isKindOfClass(MKUserLocation) { 
     return nil 
    } 

    // Reuse the annotation if possible 
    var annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier(identifier) 

    if annotationView == nil 
    { 
     annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier) 
     annotationView!.canShowCallout = true 
    } 

    annotationView!.image = UIImage(named: "custom_pin.png") 

    let detailButton: UIButton = UIButton(type: UIButtonType.DetailDisclosure) 
    annotationView!.rightCalloutAccessoryView = detailButton 

    print(annotationView!.image) 

    return annotationView 
} 

Vielen Dank im Voraus,

Grüße. Hier

Antwort

15

ist die Antwort:

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

    let identifier = "MyPin" 

    if annotation.isKindOfClass(MKUserLocation) { 
     return nil 
    } 

    let detailButton: UIButton = UIButton(type: UIButtonType.DetailDisclosure) 

    if let annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier(identifier) { 
     annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: "pin") 
     annotationView.canShowCallout = true 
     annotationView.image = UIImage(named: "custom_pin.png") 
     annotationView.rightCalloutAccessoryView = detailButton 
    } 
    else { 
     annotationView.annotation = annotation 
    } 

    return annotationView 
} 

Grüße

+1

Vielen Dank für Ihre Lösungen. Es half mir auch –

+0

funktioniert nicht für Swift 2.2 – DeyaEldeen

+0

Down abgestimmt. 1) Die Instanz "annotationView" wird im if-let-Bereich erstellt und ist in else-scope nicht vorhanden. 2) Wenn Sie eine Annotationsansicht erfolgreich entfernen können, sollten Sie diese verwenden und keine neue Instanz erstellen. Die neue Instanz sollte im Bereich "else-scope" erstellt werden, in der ein wiederverwendbares Objekt nicht entfernt werden kann. – esbenr

41

Die akzeptierte Antwort nicht funktioniert, wie es annotationView uninitialized in else Block hat.

Hier ist eine bessere Lösung. Es reiht Anmerkungsansicht, wenn möglich, oder erstellt eine neue, wenn nicht:

Swift 3, 4:

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { 
    // Don't want to show a custom image if the annotation is the user's location. 
    guard !(annotation is MKUserLocation) else { 
     return nil 
    } 

    // Better to make this class property 
    let annotationIdentifier = "AnnotationIdentifier" 

    var annotationView: MKAnnotationView? 
    if let dequeuedAnnotationView = mapView.dequeueReusableAnnotationView(withIdentifier: annotationIdentifier) { 
     annotationView = dequeuedAnnotationView 
     annotationView?.annotation = annotation 
    } 
    else { 
     annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: annotationIdentifier) 
     annotationView?.rightCalloutAccessoryView = UIButton(type: .detailDisclosure) 
    } 

    if let annotationView = annotationView { 
     // Configure your annotation view here 
     annotationView.canShowCallout = true 
     annotationView.image = UIImage(named: "yourImage") 
    } 

    return annotationView 
} 

Swift 2.2:

func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? { 
    // Don't want to show a custom image if the annotation is the user's location. 
    guard !annotation.isKindOfClass(MKUserLocation) else { 
     return nil 
    } 

    let annotationIdentifier = "AnnotationIdentifier" 

    var annotationView: MKAnnotationView? 
    if let dequeuedAnnotationView = mapView.dequeueReusableAnnotationViewWithIdentifier(annotationIdentifier) { 
     annotationView = dequeuedAnnotationView 
     annotationView?.annotation = annotation 
    } 
    else { 
     let av = MKAnnotationView(annotation: annotation, reuseIdentifier: annotationIdentifier) 
     av.rightCalloutAccessoryView = UIButton(type: .DetailDisclosure) 
     annotationView = av 
    } 

    if let annotationView = annotationView { 
     // Configure your annotation view here 
     annotationView.canShowCallout = true 
     annotationView.image = UIImage(named: "yourImage") 
    } 

    return annotationView 
} 
+1

Dies half mir viel mehr als die angenommene Antwort, vielen Dank @Andrey Gordeev – Alk

+1

Wow !!! Das hat mich ernsthaft gerettet !!! Ich hatte einige ernsthafte Perf Probleme, aber dieses Beispiel zu sehen, wie man den Bezeichner richtig verwendet, half wirklich. Ich dachte, ich würde es auch richtig benutzen. Dies sollte die akzeptierte Antwort sein! – BryHaw

+0

Großartig! Vielen Dank. – Raja

0

SWIFT 3,4

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { 

    if annotation.isKind(of: MKUserLocation.self) { 
     return nil 
    } 

    let annotationIdentifier = "AnnotationIdentifier" 

    var pinView = mapView.dequeueReusableAnnotationView(withIdentifier: annotationIdentifier) 
    if (pinView == nil) { 
     pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: annotationIdentifier) 
    } 

    pinView?.canShowCallout = false 

    return pinView 
}