FS.O6
FS.O6

Reputation: 1464

Dynamically change MGLPointAnnotation image on Mapbox iOS SDK

I have an app that uses a map of Mapbox on its iOS SDK and present markers (MGLPointAnnotation) on it.

I want to change the image of a marker when it selected.

MGLPointAnnotation has no image property and I've tried to call the delegate method mapView(mapView, imageForAnnotation annotation) but it didn't work.

Any idea how can I do that?

Thanks!

Upvotes: 3

Views: 2447

Answers (2)

Eduardo Parada
Eduardo Parada

Reputation: 69

I managed to change the image when you click on a different image.

var poiSelected: MGLAnnotation?

private func printPoiImage(with name: String, annotation: MGLAnnotation, mapView: MGLMapView) {
    let id = "\(annotation.coordinate.latitude)+\(annotation.coordinate.longitude)"
    let annotationImage = mapView.dequeueReusableAnnotationImage(withIdentifier: id)
    annotationImage?.image = UIImage(named: name)
}

func mapView(_ mapView: MGLMapView, didSelect annotation: MGLAnnotation) {
        if self.poiSelected == nil {
            self.poiSelected = annotation
            self.printPoiImage(with: "PoiOn", annotation: annotation, mapView: mapView)
        }
    }

    func mapView(_ mapView: MGLMapView, didDeselect annotation: MGLAnnotation) {
        self.poiSelected = nil
        self.printPoiImage(with: "PoiOff", annotation: annotation, mapView: mapView)
    }

    func mapView(_ mapView: MGLMapView, imageFor annotation: MGLAnnotation) -> MGLAnnotationImage? {
        let id = "\(annotation.coordinate.latitude)+\(annotation.coordinate.longitude)"

        var annotationImage = mapView.dequeueReusableAnnotationImage(withIdentifier: id)

        if annotationImage == nil {

            var image: UIImage?
            if self.poiSelected == nil {
                image = UIImage(named: "PoiOff")
            } else {
                image = UIImage(named: "PoiOn")
            }

            guard var imageWrap = image else { return nil }
            imageWrap = imageWrap.withAlignmentRectInsets(UIEdgeInsets(top: 0, left: 0, bottom: imageWrap.size.height/2, right: 0))
            annotationImage = MGLAnnotationImage(image: imageWrap, reuseIdentifier: id)
        }

        return annotationImage
    }

Upvotes: 0

Peter Pohlmann
Peter Pohlmann

Reputation: 1508

  1. I'm pretty sure that there is no way to change an annotation after is has been added to the map (except it is an annotationView)

  2. The mapView(mapView, imageForAnnotation annotation) gets only called, when you add an annotation.

  3. What you can do is to to use the didselect delegete

    func mapView(_ mapView: MGLMapView, didSelect annotationView: MGLAnnotationView){ //code }

And set there a new annotation at the same location but this time with your desired image. Then the image annotation delegate gets called, where you define your image

func mapView(_ mapView: MGLMapView, imageFor annotation: MGLAnnotation) -> MGLAnnotationImage? {
//code
}

Here's an example for a customer marker image: https://www.mapbox.com/ios-sdk/examples/marker-image/

Upvotes: 1

Related Questions