web-dev-qa-db-fra.com

Swift différentes images pour l'annotation

J'ai réussi à obtenir une icône personnalisée pour une épingle d'annotation dans Swift, mais maintenant je suis toujours bloqué en utilisant 2 images différentes pour des annotations différentes. À l'heure actuelle, un bouton ajoute une annotation à la carte. Il devrait y avoir un autre bouton qui ajoute également une annotation mais avec une autre icône.

Existe-t-il un moyen d'utiliser le reuseId pour cela?

class ViewController: UIViewController, MKMapViewDelegate {

@IBOutlet weak var Map: MKMapView!

@IBAction func btpressed(sender: AnyObject) {

    var lat:CLLocationDegrees = 40.748708
    var long:CLLocationDegrees = -73.985643
    var latDelta:CLLocationDegrees = 0.01
    var longDelta:CLLocationDegrees = 0.01

    var span:MKCoordinateSpan = MKCoordinateSpanMake(latDelta, longDelta)
    var location:CLLocationCoordinate2D = CLLocationCoordinate2DMake(lat, long)
    var region:MKCoordinateRegion = MKCoordinateRegionMake(location, span)

    Map.setRegion(region, animated: true)


    var information = MKPointAnnotation()
    information.coordinate = location
    information.title = "Test Title!"
    information.subtitle = "Subtitle"

    Map.addAnnotation(information)
}

func mapView(mapView: MKMapView!, viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! {
    if !(annotation is MKPointAnnotation) {
        return nil
    }

    let reuseId = "test"

    var anView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId)
    if anView == nil {
        anView = MKAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
        anView.image = UIImage(named:"1.png")
        anView.canShowCallout = true
    }
    else {
        anView.annotation = annotation
    }

    return anView
}
30
Fabian Boulegue

Dans la méthode déléguée viewForAnnotation, définissez image sur la base de laquelle annotation la méthode est appelée.

Assurez-vous de le faire après la vue est retirée de la file d'attente ou créée (et pas seulement dans le if anView == nil partie). Sinon, les annotations qui utilisent une vue en file d'attente afficheront l'image de l'annotation qui a utilisé la vue précédemment.

Avec le MKPointAnnotation de base, une façon grossière de distinguer les annotations est par leur title mais ce n'est pas très flexible.

Une meilleure approche consiste à utiliser une classe d'annotation personnalisée qui implémente le protocole MKAnnotation (un moyen simple de le faire est de sous-classer MKPointAnnotation) et d'ajouter toutes les propriétés nécessaires pour aider à implémenter la logique personnalisée.

Dans la classe personnalisée, ajoutez une propriété, par exemple imageName, que vous pouvez utiliser pour personnaliser l'image en fonction de l'annotation.

Cet exemple de sous-classes MKPointAnnotation:

class CustomPointAnnotation: MKPointAnnotation {
    var imageName: String!
}

Créez des annotations de type CustomPointAnnotation et définissez leur imageName:

var info1 = CustomPointAnnotation()
info1.coordinate = CLLocationCoordinate2DMake(42, -84)
info1.title = "Info1"
info1.subtitle = "Subtitle"
info1.imageName = "1.png"

var info2 = CustomPointAnnotation()
info2.coordinate = CLLocationCoordinate2DMake(32, -95)
info2.title = "Info2"
info2.subtitle = "Subtitle"
info2.imageName = "2.png"

Dans viewForAnnotation, utilisez la propriété imageName pour définir le image de la vue:

func mapView(mapView: MKMapView!, viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! {
    if !(annotation is CustomPointAnnotation) {
        return nil
    }

    let reuseId = "test"

    var anView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId)
    if anView == nil {
        anView = MKAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
        anView.canShowCallout = true
    }
    else {
        anView.annotation = annotation
    }

    //Set annotation-specific properties **AFTER**
    //the view is dequeued or created...

    let cpa = annotation as CustomPointAnnotation
    anView.image = UIImage(named:cpa.imageName)

    return anView
}
81
user467105

iOS Swift Code avec l'aide d'Anna et Fabian Boulegue:

import UIKit
import MapKit

class ViewController: UIViewController, MKMapViewDelegate {

    @IBOutlet weak var mapView: MKMapView!

    override func viewDidLoad() {
        super.viewDidLoad()

        self.mapView.delegate = self

        var info1 = CustomPointAnnotation()
        info1.coordinate = CLLocationCoordinate2DMake(26.889281, 75.836042)
        info1.title = "Info1"
        info1.subtitle = "Subtitle"
        info1.imageName = "flag.png"

        var info2 = CustomPointAnnotation()
        info2.coordinate = CLLocationCoordinate2DMake(26.862280, 75.815098)
        info2.title = "Info2"
        info2.subtitle = "Subtitle"
        info2.imageName = "flag.png"

        mapView.addAnnotation(info1)
        mapView.addAnnotation(info2)
    }

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

        println("delegate called")

        if !(annotation is CustomPointAnnotation) {
            return nil
        }

        let reuseId = "test"

        var anView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId)
        if anView == nil {
            anView = MKAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
            anView.canShowCallout = true
        }
        else {
            anView.annotation = annotation
        }

        //Set annotation-specific properties **AFTER**
        //the view is dequeued or created...

        let cpa = annotation as CustomPointAnnotation
        anView.image = UIImage(named:cpa.imageName)

        return anView
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

class CustomPointAnnotation: MKPointAnnotation {
    var imageName: String!
}
12
Vinod Joshi