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
- Using MKPlacemark.
- Using MKPointAnnotation.
- 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])
}
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
}
}
}
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
}
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?
In Controller You can create an array of Pin and whenever you display the pins use that array
Muneeb!! Man! thanks so much. That helped. I am displaying my array of pins now.
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?
You can check in annotation type and when it matches render it on map