MKAnnotationView – Display Custom Pin Image

This Swift code example will demonstrate how to add custom image to a MKAnnotationView.

The code example below will cover:

  • Import CoreLocation framework,
  • Create MKMapView programmatically,
  • Add MapView as subview
  • Determine user’s current location
  • Set current region on the map
  • Create MKPointAnnotation with custom title
  • Drop MKPointAnnotation as a Pin at user’s current location
  • Create MKAnnotationView with custom image

Create MKAnnotationView with custom image

To customize MapView annotations you will need to make your ViewController conform to a MKMapViewDelegate protocol and implement the following function:

 
optional public func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView?

Below is a very simple example of how you can do it:

 
 func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView?
    {
        if !(annotation is MKPointAnnotation) {
            return nil
        }
        
        let annotationIdentifier = "AnnotationIdentifier"
        var annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier(annotationIdentifier)
        
        if annotationView == nil {
            annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: annotationIdentifier)
            annotationView!.canShowCallout = true
        }
        else {
            annotationView!.annotation = annotation
        }
        
        let pinImage = UIImage(named: "customPinImage")
        annotationView!.image = pinImage
 
       return annotationView   
    }

Display Custom Pin Image for MKAnnotationView. Complete Example.

 
import UIKit
import CoreLocation
import MapKit

class ViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {

    @IBOutlet weak var mapView: MKMapView!
    var locationManager:CLLocationManager!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)
        
        locationManager = CLLocationManager()
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
    }
    
    override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)
        
        determineCurrentLocation()
    }
    
    func determineCurrentLocation()
    {

        locationManager.requestWhenInUseAuthorization()
        
        if CLLocationManager.locationServicesEnabled() {
            //locationManager.startUpdatingHeading()
            locationManager.startUpdatingLocation()
        }
    }
 
    func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        let userLocation:CLLocation = locations[0] as CLLocation
        print("Updating location")
        // Call stopUpdatingLocation() to stop listening for location updates,
        // other wise this function will be called every time when user location changes.
       // manager.stopUpdatingLocation()
        
        let center = CLLocationCoordinate2D(latitude: userLocation.coordinate.latitude, longitude: userLocation.coordinate.longitude)
        let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01))
        
        mapView.setRegion(region, animated: true)
        
        // Drop a pin at user's Current Location
        let myAnnotation: MKPointAnnotation = MKPointAnnotation()
        myAnnotation.coordinate = CLLocationCoordinate2DMake(userLocation.coordinate.latitude, userLocation.coordinate.longitude);
        myAnnotation.title = "Current location"
        mapView.addAnnotation(myAnnotation)
    }
    
    func locationManager(manager: CLLocationManager, didFailWithError error: NSError)
    {
        print("Error \(error)")
    }
    
    func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView?
    {
        if !(annotation is MKPointAnnotation) {
            return nil
        }
        
        let annotationIdentifier = "AnnotationIdentifier"
        var annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier(annotationIdentifier)
        
        if annotationView == nil {
            annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: annotationIdentifier)
            annotationView!.canShowCallout = true
        }
        else {
            annotationView!.annotation = annotation
        }
        
        let pinImage = UIImage(named: "customPinImage")
        annotationView!.image = pinImage

        return annotationView
    }
}

The below video tutorial will demonstrate how to create MapView programmatically as well as how to create MapView using the Storyboard and will walk you through the source code that determines user’s current location in greater details.

CoreLocation and MKMapKit – Drop a pin(MKAnnotationView) at user’s current location. Video tutorial


Learn iOS Development with these Video Courses

The Complete iOS 11 & Swift Developer Course - Build 20 Apps

Use Xcode 9 & Swift 4 to make real apps like Uber and Instagram, with CoreML & ARKit. Includes AWS Credit and much more. Preview this video course. icon

How to Make a Freaking iPhone App - iOS 11 and Swift 4

iPhone App Development from scratch. Learn how to make iOS apps using Xcode 9. The Basics Include Pokemon Go & Snapchat. Learn to build iOS Apps with Xcode 9 and Swift 4. How to Make a Freaking iPhone App - iOS 11 and Swift 4 icon

iOS 11 and Xcode 9 - Complete Swift 4 & Objective-C Course

A Complete iOS 11 and Xcode 9 Course with Swift 4 & Objective-C. Preview this video course. iOS 11 and Xcode 9 - Complete Swift 4 & Objective-C Course icon