Search code examples
iosswiftgoogle-mapsswift4google-maps-sdk-ios

Google Maps different marker images for tapped and unselected state


is there a way to add an ID, a case or something similar, in order to set custom marker images for selected and unselected state?

I have multiple markers with different names/title, and i need that a specific type of marker has another image for selected and unselected state.

For example:

marker1 - marker_1_image

marker2 - marker_2_image

Atm I am only able to set 2 images with the right images but If I click on a marker it will hereditate the the specific type set on the ".contains" function. I did a ".contains" function in order to find a specific string in a JSON response under the POI/location name. eg: currentAtmModel?.placeName?.contains("restaurant"), so markers with the name "restaurant" will be shown with a specific icon image.

I'm using the latest version of Google Maps SDK for iOS.

Here is my code:

var markersModel: [MarkersLocation] = [] {
        didSet {
            updateAllMarkers()
        }
    }

private func updateAllMarkers() {
        for selectedPOIMarker in markersModel {
            let currentPOIModel = selectedPOIMarker.location
            let latitude = currentPOIModel?.coordinates?.latitude
            let longitude = currentPOIModel?.coordinates?.longitude

            let marker = GMSMarker()
            marker.appearAnimation = GMSMarkerAnimation.pop
            marker.position = CLLocationCoordinate2D(latitude: latitude ?? 0, longitude: longitude ?? 0)

            if (currentPOIModel?.placeName?.contains("db")) ?? false {
                marker.icon = restaurantMarkerIcon(selected: false)
            } else {
                marker.icon = normalMarkerIcon(selected: false)
            }
            marker.map = googleMapsView
        }
    }

extension POILocatorViewController: GMSMapViewDelegate {
    func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {
        googleMapsView.selectedMarker = marker
        googleMapsView.animate(toLocation: marker.position)
        googleMapsView.selectedMarker?.icon = normalMarkerIcon(selected: true)
        googleMapsView.selectedMarker?.icon = restaurantMarkerIcon(selected: true)
        guard let markersModel = markersModel.filter({ $0.location?.coordinates?.latitude == marker.position.latitude && $0.location?.coordinates?.longitude == marker.position.longitude }).first else { return false }
        coordinatorDelegate?.poiLocatorViewController(self, didTap: markersModel, currentLocation: currentLocation)

        return true
    }
}

extension POILocatorViewController {
    func reloadMarker() {
        googleMapsView.selectedMarker?.icon = normalMarkerIcon(selected: false)
        googleMapsView.selectedMarker?.icon = restaurantMarkerIcon(selected: false)
        googleMapsView.selectedMarker = nil
    }
}

Solution

  • When you will add a marker to GMSMapView, you can assign a unique identifier to GMSMarker using it's zIndex property to identify the marker.

     let marker = GMSMarker()
     marker.appearAnimation = GMSMarkerAnimation.pop
     marker.position = CLLocationCoordinate2D(latitude: latitude ?? 0, longitude: longitude ?? 0)
    
     if (currentPOIModel?.placeName?.contains("db")) ?? false {
         marker.icon = restaurantMarkerIcon(selected: false)
     } else {
         marker.icon = normalMarkerIcon(selected: false)
     }
     marker.zIndex = Int32(id) //your marker unique id
     marker.map = googleMapsView
    

    And then you can get marker unique identifier in marker in didTap method to set different image or to perform other operation based on marker

    extension POILocatorViewController: GMSMapViewDelegate {
        func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {
    
            print("Marker Identifier = \(marker.zIndex)") //Get your marker your unique identifier here.
            return true
        }
    }
    

    Hope this will helpful to you.