MapKit | Adding Custom Annotations to a Map | Swift + UIKit

Tianna Lewis
3 min readNov 15, 2021

A short series about working with iOS MapKit.

Continuing with this short series, our next thing to tackle is how to add annotations to a map, which are the red pins you often see on maps. We are also going to take things a step further and move away from the default red pin and customize our annotations to use our own custom images. We are going to be building on top of the project that was started in the earlier article, so if you are interested in seeing what we have accomplished so far I recommend checking that out first.

As a refresher, this mini-series focuses on 3 things, and we are currently covering topic 2 of 3.

  1. Adding a MapView Programmatically
  2. Adding Custom Annotations to a Map [You are Here]
  3. Drawing a Route on a Map

Drop a Pin

Like every other new feature or action, we have had to implement we are going to write a function that will be responsible for dropping our pins. For this project, we are only dropping two pins, but feel free to drop as many as you want.

//Function to add a Pin
func addPins() {
if routeCoordinates.count != 0 {
let startPin = MKPointAnnotation()
startPin.title = "start"
startPin.coordinate = CLLocationCoordinate2D(
latitude: routeCoordinates[0].coordinate.latitude,
longitude: routeCoordinates[0].coordinate.longitude
)
mapView.addAnnotation(startPin)

let endPin = MKPointAnnotation()
endPin.title = "end"
endPin.coordinate = CLLocationCoordinate2D(
latitude: routeCoordinates.last!.coordinate.latitude,
longitude: routeCoordinates.last!.coordinate.longitude
)
mapView.addAnnotation(endPin)
}
}

This function won’t be run unless it is called from somewhere so update viewDidLoad to call this function.

At this point, I recommend building and running the project to make sure everything is working as you expect. If you’re following along you should see two pins dropped on the island of Jamaica.

Customize Pins

To be able to have custom markers, you need images to replace the default marker image. Upload the images you intend to replace, remember to check out the project repo on GitHub, for the resource files used in this project if you are following along. You will place them into the Asset folder in the project structure in the left sidebar.

Now we are finally going to update the MKMapViewDelegate extension we added at the bottom in the earlier article. We need to add the “viewFor annotation” function stub and inside the function, we need to set the annotationView, check if it is present or not, and if not create it, then we can check the annotation title and determine the image to use based on that, then return the annotationView. This all looks like this.

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if annotation is MKUserLocation {
return nil
}

var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: "custom")

if annotationView == nil {
//Create View
annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: "custom")
} else {
//Assign annotation
annotationView?.annotation = annotation
}

//Set image
switch annotation.title {
case "end":
annotationView?.image = UIImage(named: "pinEnd")
case "start":
annotationView?.image = UIImage(named: "pinStart")
default:
break
}

return annotationView
}

Now if you build and run you should see the default markers replaced by our custom images.

Next:

2/3 of the way through the series with only one more article to go, how to draw a route between two points, which is up next.

Links

YouTube Series
GitHub

--

--

Tianna Lewis

Learning and Building in the Open. Check out what I’ve been up to at tiannahenrylewis.com.