14.2. Phase 2: Annotations and Accessories for a certain place

In this module, we will learn how to annotate a place in a particular coordinate on the map view. For example, we can annotate Northeastern University on the map view like the following:

Defining a Place class with MKAnnotation

We will define a class named Place, adopting the MKAnnotation protocol to annotate places on the map view. So let's create a new file named 'Place.swift' and put the following code there:

In the above code:

  • The class Place extends another Swift class NSObject, and adopts MKAnnotation protocol. MKAnnotation is a protocol that allows a Swift object to adopt MapKit's annotation-specific data and use the object directly as a place on the map.

  • On lines 12 through 14, we keep three variables to use in the annotation for a place.

    • title - the name of the place.

    • coordinate - the lat and long coordinates of the place.

    • info - additional details you may want to store.

    • You can use as many variables as you want to store more data regarding a place.

  • Our initializer for the class Place is defined on lines through 16 through 20.

  • Then we also initialize a variable mapItem of the type MKMapItem, to interact with the place on the map. MKMapItem class contains the details of a map location, like a placemark, coordinate, name, etc.

    • The placemark in a map item is the details of the place the map item represents, like the coordinate, physical address, phone number, images, etc. For now, we keep an empty dictionary for the addressDictionary of the placemark.

  • Between lines 23 and 25, we used guard-let instead of if-let.

What is guard-let?

guard-let is very similar to if-let to unwrap an optional value. guard-let is often used when you do not need to deal with the unwrapped value immediately and would use it later. So, we get the unwrapped value and store it in a constant for later use. For more, visit: https://www.hackingwithswift.com/quick-start/understanding-swift/when-to-use-guard-let-rather-than-if-let

Display an Annotated Place on Map

Let's open the ViewController.swift file, and put the following code there:

In the above code:

  • On lines 19 through 23, we create a Place object, northeastern with the details of Northeastern University (title, coordinate, and info).

  • Then we add the Place northeastern as an annotation on the map on line 25.

Let's run the app.

You can see there is a red bubble on the place northeastern. That is the placemark we talked about thus far.

Interacting with the Annotations

Now to be able to interact with the bubble, we need to adopt a protocol MKMapViewDelegate. We need to implement two adopted mapView() methods with parameters viewFor and calloutAccessoryControlTapped.

Let's create a new file MapAnnotationDelegate.swift and put the following code there:

In the above code:

  • Between lines 12 through 15, we need to create an annotation view to display the placemark details. We can

  • Between lines 17 through 20, we need to write the logic to handle in case the user taps on the accessory button of the annotation.

Creating Annotation View

Let's put the following code in the mapView() method for viewFor (first method in the above code):

In the above code:

  • On line 3, we define a new annotation from the annotation parameter as a Place object.

  • Between line 7 and 18 we check if there is a reusable annotation already populated on screen,

    • If yes, then we reuse the current annotation view.

    • Else, we create a new annotation

      • We set the annotation view's canShowCallout parameter as true. It means it can display a callout interactive annotation view on this place.

      • Then we add a right accessory button on the callout annotation view.

Delegating the User Interaction on the Callout

Let's put the following code in the mapView() method for calloutAccessoryControlTapped (second method):

In the above code:

  • The method gets triggered when the user taps the accessory callout right button.

  • It displays an alert controller with two actions (lines 7 through 21):

    • On lines 13 through 18, we add the navigation action to the alert controller with a button named 'Navigation.'

      • On lines 14 through 16, we define the launchOptions for opening navigation in Apple Maps. We set the navigation direction type as driving directions on line 15.

      • And on line 17, we open Apple Maps to navigate to the place annotated.

    • On line 20, we add a Cancel action for the alert controller.

    • Then finally, on line 21, we present the alert controller.

We have a final task to do. We need to patch the delegate of the mapView to ViewController. Let's open ViewController.swift file and add the following line in viewDidLoad() method: mapView.mapView.delegate = self.

Let's run the app.

We first load the screen and display the annotation for Northeastern. Then we change the current simulator location to Apple's headquarters location. Then we try the navigation with annotation. It opens the Apple Map, and we can drive!

Code so far

41KB
Open

Last updated

Was this helpful?