Codementor Events

MapKit — Map Pin and Annotation

Published Dec 11, 2019
MapKit — Map Pin and Annotation

In this article will discuss how to set the pin on a specific location on MapKit with its proper implementation using Swift. If I missed something let me know in comments.

Let’s get started:

We will continue from our previous article if you miss that you can read it here. As we get the location of the user, now we will set a pin on the user location. For placing a pin in MapKit we have 3 ways

  1. Using MKPlacemark.
  2. Using MKPointAnnotation.
  3. Using MKAnnotation.

1. Using MKPlacemark:

MKPlacemark is the simplest way to place a pin on the map. It just required coordinates of the place to where to set pin. Use this function to set pin:

func setPinUsingMKPlacemark(location: CLLocationCoordinate2D) {
   let pin = MKPlacemark(coordinate: location)
   let coordinateRegion = MKCoordinateRegion(center: pin.coordinate, latitudinalMeters: 800, longitudinalMeters: 800)
   mapView.setRegion(coordinateRegion, animated: true)
   mapView.addAnnotation(pin)
}

2. Using MKPointAnnotation:

MKPointAnnotation is also the simplest way to place a pin on the map.

func setPinUsingMKPointAnnotation(location: CLLocationCoordinate2D){
   let annotation = MKPointAnnotation()
   annotation.coordinate = location
   annotation.title = "Here"
   annotation.subtitle = "Device Location"
   let coordinateRegion = MKCoordinateRegion(center: annotation.coordinate, latitudinalMeters: 800, longitudinalMeters: 800)
   mapView.setRegion(coordinateRegion, animated: true)
   mapView.addAnnotation(annotation)
}

3. Using MKAnnotation:

For MKAnnotation we have to make a model class for the pin which holds the data of the pins but it doesn’t provide a visual representation for the pin on the map.

import MapKit
class MapPin: NSObject, MKAnnotation {
   let title: String?
   let locationName: String
   let coordinate: CLLocationCoordinate2D
init(title: String, locationName: String, coordinate: CLLocationCoordinate2D) {
      self.title = title
      self.locationName = locationName
      self.coordinate = coordinate
   }
}

Use this function to set a pin on the map :

func setPinUsingMKAnnotation(location: CLLocationCoordinate2D) {
   let pin1 = MapPin(title: “Here”, locationName: “Device Location”, coordinate: location)
   let coordinateRegion = MKCoordinateRegion(center: pin1.coordinate, latitudinalMeters: 800, longitudinalMeters: 800)
   mapView.setRegion(coordinateRegion, animated: true)
   mapView.addAnnotations([pin1])
}

Default Pin on Map
From all the above methods default pin will be rendered on the map and you can also change title and subtitle. In above all methods you can see there is a setRegion method which is used to focus on a given location. Now we will set the custom pin on the map. For this we have to impliment delegate for map view so we write this in our setup method.

mapView.delegate = self

Now we will write delegate methods:

//MARK: — MKMapView Delegate Methods
extension ViewController: MKMapViewDelegate {
   func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
   
      let Identifier = “Pin”
      let annotationView = annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: Identifier) ?? MKAnnotationView(annotation: annotation, reuseIdentifier: Identifier)
   
      annotationView.canShowCallout = true
      if annotation is MKUserLocation {
         return nil
      } else if annotation is MapPin {
         annotationView.image =  UIImage(imageLiteralResourceName: "Pin")
         return annotationView
      } else {
         return nil
      }
   }
}

Custom Pin on map

Cluster Annotation:

When we have many pins at same place the it look vired so Apple introduse MKClusterAnnotation from which 1 pin is shown with the pin count at that location which is more easy to handle for clustering just write following lines of code in above delegate methods

if #available(iOS 11.0, *) {
   annotationView.clusteringIdentifier = “PinCluster”
} else {
   // Fallback on earlier versions
}

Clustering in Map
Map

Discover and read more posts from Muneeb Ali
get started
post comments5Replies
Robert Cleary
3 years ago

Muneeb, this is great. Thanks. If I wanted to use an array that is always being updated to drop pins, how would I do this?

Muneeb Ali
3 years ago

In Controller You can create an array of Pin and whenever you display the pins use that array

Robert Cleary
3 years ago

Muneeb!! Man! thanks so much. That helped. I am displaying my array of pins now.

Robert Cleary
3 years ago

one more question… I have several annotation types. I want my viewForAnnotation to set up a different annotation based on the type of annotation dropped. I know that I do that in the viewForAnnotation, but how do I get the glyph image, the color, etc for each different kind of annotation?

Muneeb Ali
3 years ago

You can check in annotation type and when it matches render it on map

Show more replies