Search code examples
google-maps-sdk-ios

Custom Info Window for Google Maps


I'd like to make a custom Info Window for Google Maps for iOS like the photo below. Is it possible to extend GMSOverlay like GMSMarker, GMSPolyline, and GMSPolygon do to create custom graphics?

enter image description here


Solution

  • For those who's trying to add buttons to a custom view representing info window - it seems to be impossible to do, because Google Maps SDK draws it as an image or something like this. But there is a quite simple solution:

    1. You have to create a custom view with buttons and whatever you need to be displayed in your info window.
    2. Add it as a subview in your mapView(mapView: GMSMapView, didTapMarker marker: GMSMarker) method. You can set a position of a custom view by getting a coordinates of a marker tapped with a help of mapView.projection.pointForCoordinate(marker.position)
    3. Your custom view possibly has to change it position by following camera position, so you have to handle mapView(mapView: GMSMapView, didChangeCameraPosition position: GMSCameraPosition) where you could easily update your custom view position.

      var infoWindow = CustomInfoView()
      var activePoint : POIItem?
      
      func mapView(mapView: GMSMapView, didTapMarker marker: GMSMarker) -> Bool {
          if let poiItem = marker as? POIItem {
          // Remove previously opened window if any
              if activePoint != nil {
                  infoWindow.removeFromSuperview()
                  activePoint = nil
              }
              // Load custom view from nib or create it manually
              // loadFromNib here is a custom extension of CustomInfoView
              infoWindow = CustomInfoView.loadFromNib()
              // Button is here
              infoWindow.testButton.addTarget(self, action: #selector(self.testButtonPressed), forControlEvents: .AllTouchEvents)
      
              infoWindow.center = mapView.projection.pointForCoordinate(poiItem.position)
              activePoint = poiItem
              self.view.addSubview(infoWindow)
          }
          return false
      }
      
      func mapView(mapView: GMSMapView, didChangeCameraPosition position: GMSCameraPosition) {
      
          if let tempPoint = activePoint {
              infoWindow.center = mapView.projection.pointForCoordinate(tempPoint.position)
          }
      
      }