Adding Annotations to a Map

Learn how to let users add annotations (pins) to an MKMapView by performing a long-press gesture on the map in your Swift application.

Adding Annotations to a Map

Note:

This tutorial covers how to use UILongPressGestureRecognizer to detect a long press on a map and drop a pin (MKPointAnnotation) at that location.

Overview

You may want to allow users to place a marker on a Map View when they long-press on a location. To achieve this, we will implement the following steps:

  • Use UILongPressGestureRecognizer to detect when the user holds their finger down.
  • Create an @objc function to be triggered by the gesture.
  • Inside the function:
    • Determine the coordinates of the touched point on the map.
    • Add an MKPointAnnotation at that location.

Reference:

Step 1: Setting up the UILongPressGestureRecognizer

First, let's define our UILongPressGestureRecognizer in viewDidLoad. We will specify a minimum press duration (e.g., 3 seconds) for the gesture to be recognized. The recognizer will trigger an @objc function, which we will define in the next step.

// In viewDidLoad()
let gestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(chooseLocation(gestureRecognizer:)))
gestureRecognizer.minimumPressDuration = 3
mapView.addGestureRecognizer(gestureRecognizer)

Step 2: Implementing the @objc Function

Next, create the function that the gesture recognizer will call. We pass the gestureRecognizer itself into the function so we can access information about the touch event.

Here is the complete function:

@objc func chooseLocation(gestureRecognizer: UILongPressGestureRecognizer) {
    // 1. Check if the gesture has begun
    if gestureRecognizer.state == .began {
        
        // 2. Get the point where the user touched on the screen
        let touchPoint = gestureRecognizer.location(in: self.mapView)
        
        // 3. Convert the screen touch point to map coordinates (latitude and longitude)
        let touchCoordinates = self.mapView.convert(touchPoint, toCoordinateFrom: self.mapView)
        
        // 4. Create an annotation object
        let annotation = MKPointAnnotation()
        annotation.coordinate = touchCoordinates
        
        // 5. (Optional) Set a title and subtitle for the pin
        annotation.title = "New Pin"
        annotation.subtitle = "My Custom Location"
        
        // 6. Add the annotation to the map
        self.mapView.addAnnotation(annotation)
    }
}

Explanation:

  • Line 2: We check if the gestureRecognizer.state is .began. This ensures our code runs only once when the long press starts, not continuously while the finger is held down.
  • Line 5: We get the CGPoint where the user touched within the mapView.
  • Line 8: We convert the CGPoint to a CLLocationCoordinate2D (latitude and longitude).
  • Lines 11-16: We create an MKPointAnnotation, set its coordinate and optional title/subtitle, and finally add it to the map with mapView.addAnnotation().

Now, when a user presses and holds on the map for three seconds, a pin will be dropped at that location.


Note:

This is a basic implementation of adding annotations. MKMapViewDelegate provides further methods to customize the appearance of the annotation pins, such as changing their color or using custom images.