How to change google maps marker color when selected in swift?
Asked Answered
P

4

11

I have a view controller with a GMSMapView and have loaded a number of markers onto the map. I can change which marker is selected with mapView.selectedMarker = ... but how do I change the color of the selected marker?

Poteen answered 2/12, 2016 at 18:46 Comment(0)
P
24

You can use GMSMarker.markerImage(with: <UIColor?>) to reset a marker's icon.

Docs: Google Maps iOS SDK GMSMarker Class Reference

import GoogleMaps

// view controller
class MapViewController: UIViewController {

    // outlets
    @IBOutlet weak var mapView: GMSMapView!

    // view did load method
    override func viewDidLoad() {
        super.viewDidLoad()

        // set map view delegate
        mapView.delegate = self
    }
}

// extension for GMSMapViewDelegate
extension MapViewController: GMSMapViewDelegate {

    // tap map marker
    func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {
        print("didTap marker \(marker.title)")

        // remove color from currently selected marker
        if let selectedMarker = mapView.selectedMarker {
            selectedMarker.icon = GMSMarker.markerImage(with: nil)
        }

        // select new marker and make green
        mapView.selectedMarker = marker
        marker.icon = GMSMarker.markerImage(with: UIColor.green)

        // tap event handled by delegate
        return true
    }
}
Poteen answered 2/12, 2016 at 18:46 Comment(3)
If you tap a marker, then tap the ground, then tap another marker, there will be two markers selectedNaamana
As @Naamana suggested there is issue with your solution.Gash
Ya it seems that when you set the selected marker manually the behavior described by @Naamana occurs. The google maps api automatically sets the selected marker for you so there's no need for this line mapView.selectedMarker = marker.Latin
W
3

Simple Way Swift 5

marker.icon = GMSMarker.markerImage(with: UIColor.green)
Wheelhouse answered 4/9, 2018 at 14:11 Comment(0)
L
2

The accepted answer wasn't working for me because if a user tapped a non-marker on the map, selectedMarker would be set to nil. If the user then tapped another marker, triggering the didTap callback, the selectedMarker would be nil and thus retain its selected state/color.

The fix for me was to remove that selectedMarker logic from didTap and move it to didCloseWindowOf.

Here's the code:

func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {
    marker.icon = UIImage(named: "map_marker_selected")
    return false // return false to display info window
}

func mapView(_ mapView: GMSMapView, didCloseInfoWindowOf marker: GMSMarker) {
    marker.icon = UIImage(named: "map_marker_unselected")
}

This works because when the user taps a non-marker, the info window closes which triggers didCloseInfoWindowOf.

Latin answered 12/7, 2019 at 23:2 Comment(0)
N
1

If you use RxSwift, here is an elegant solution with RxGoogleMaps

Observable.combineLatest(mapView.rx.selectedMarker,
                         mapView.rx.selectedMarker.skip(1))
    .subscribe(onNext: { (old, new) in
        old?.icon = GMSMarker.markerImage(with: nil)
        new?.icon = GMSMarker.markerImage(with: UIColor.red)
    })
    .disposed(by: disposeBag)
Naamana answered 22/3, 2018 at 12:18 Comment(1)
There is also an official Example in their docs which uses Observable.zip instead of Observable.combineLatest: github.com/RxSwiftCommunity/RxGoogleMaps/blob/master/Example/…Unreligious

© 2022 - 2024 — McMap. All rights reserved.