How to make a custom info window for your marker with Google Maps SDK for iOS

This is the third part of our Google maps SDK series. In the first tutorial, you Learned how to use the Google maps SDK to deliver search suggestions, autocompleted to the user and based on what he types in. The second tutorial is also as much important as the first, where it shows you how to implement the powerful nearby API in your app to overcome Apple limits and make your app special.

In this quick tutorial, you will customise the marker icons as well as the info window view on your map.

Without further ado, download the starter project and let’s get this done!

Make sure to open the file named CustomInfoWindow.xcworkspace since cocoapods is now integrated with the project and the Google Maps SDK for iOS is installed.

If you take a look at the Project navigator view, I added two files called CustomInfoWindow.xib and CustomInfoWindow.swift files. This two files will manage the custom info window layout and outlets. Also, few assets for the custom markers icons and info window are already added to the Assets.xcassets catalog.

Note 1: Before you continue, make sure to generate a Google API Key. If you don’t have one already, head over here to make your own (you may need to follow only steps 4 and 5 of the guide).

Note 2: Also, make sure that the bundle identifier of the app (in this case: com.medigarage.CustomInfoWindow) is registered in order to be able to use the API Key. Head over here to register the bundle identifier with the API Key if you didn’t already.

Good, now you are all set to go!

First thing to do is to provide the API Key in the app, select the AppDelegate.swift file from the Project navigator view and make the following changes:

// At the top of the file
import GoogleMaps

// In the didFinishLaunchingWithOptions method
GMSServices.provideAPIKey("YOUR_API_KEY_HERE")

Change the argument in the provideAPIKey method with the API Key you just generated in the Google APIs Console.

Next, select the ViewController.swift file from the Project navigator view and import the Google Maps SDK at the top of the file:

import GoogleMaps

We will need some properties for the maps and its data, copy the following declarations just after the class name:

var map:GMSMapView!
var longitudes:[Double]!
var latitudes:[Double]!
var architectNames:[String]!
var completedYear:[String]!

Apart the map property which works as a reference for the map view, all the properties declared above are arrays to use to provide the markers with coordinates and the info window views with informations.

Let’s initialise the arrays with some data, place the following code inside the viewDidLoad method:

latitudes = [48.8566667,41.8954656,51.5001524]
longitudes = [2.3509871,12.4823243,-0.1262362]
architectNames = ["Stephen Sauvestre","Bonanno Pisano","Augustus Pugin"]
completedYear = ["1889","1372","1859"]

The app you are about to build will show three historical monuments, in Paris, London and Rome. The arrays above are initialised with the coordinates, architects names and years of construction completion.

Next, you will load the map and make it take the whole screen frame. Always in the viewDidLoad method, implement the following code:

self.map = GMSMapView(frame: self.view.frame)
self.view.addSubview(self.map)
self.map.delegate = self

Setting the current controller as the delegate of the map view protocol requires making the class itself to adopt to the GMSMapViewDelegate protocol. To do so, just change the class declaration as below:

class ViewController: UIViewController, GMSMapViewDelegate {

Cool, time to add some markers to the map 🙂

Implement the code below in the viewDidLoad method:

for i in 0...2 {
   let coordinates = CLLocationCoordinate2D(latitude: latitudes[i], longitude: longitudes[i])
   let marker = GMSMarker(position: coordinates)
   marker.map = self.map
   marker.icon = UIImage(named: "\(i)")
   marker.infoWindowAnchor = CGPointMake(0.5, 0.2)
   marker.accessibilityLabel = "\(i)"
}

The code above will loop 3 times, the number of assets we got. It will use the lon/lat coordinates from the arrays to place the markers on the map. It will also change the default red icon with a custom image and modify the anchor of the info window slightly so it appears just above the icon. Finally the accessibilityLabel is set with the index of the icon in order to tag it with a reference for later use.

To finish up, let’s implement the mapView:markerInfoWindow: delegate method to allow the app to use the custom info window you just have in the CustomInfoWindow.xib file.

Place the following code before the class closing bracket:

func mapView(mapView: GMSMapView!, markerInfoWindow marker: GMSMarker!) -> UIView! {
   // 1
   let index:Int! = Int(marker.accessibilityLabel!)
   // 2
   let customInfoWindow = NSBundle.mainBundle().loadNibNamed("CustomInfoWindow", owner: self, options: nil)[0] as! CustomInfoWindow
   customInfoWindow.architectLbl.text = architectNames[index]
   customInfoWindow.completedYearLbl.text = completedYear[index]
   return customInfoWindow
}

The protocol method above will be called each time you select a marker, and it’s intended to return a custom view for each marker, so this is the right place where to customise the info window 🙂

First, the code will get a reference for the selected marker, this become easy since you use the accessibilityLabel property you set it earlier. second, you load the custom info window file and cast it to the CustomInfoWindow class in order to be able to use the properties hooked up in the view.

That’s it! Run the app and enjoy your work 🙂

As usual, here is the final project, feel free to leave your comment below. I am always open to your suggestions!


Discover more from SweetTutos

Subscribe to get the latest posts sent to your email.

Malek
Software craftsman with extensive experience in iOS and web development.