Most map applications let you select a point on the map. However, touching a map usually is only for moving a map around. You might want to get a coordinate at a user’s tap. In this tip, I’ll show you how to get the coordinate, and place a marker there.
Download the starter file and you’ll find an application for displaying a map of Twin Rivers Wisconsin. This is one of three contenders, the others being Evanston IL and Ithaca NY, for the first Ice Cream Sundae. Run the code and you get a map.

Stop the app. There’s a few steps for converting a touch into a coordinate. First you need tap, and react to the tap. Second, you get the coordinate of the tap in the system of the view. Finally you get a map coordinate that corresponds to the view’s coordinate.
To get the touch you use tap gesture recognizer, go to the storyboard, and type gesture into the finder.

You see several gestures. Some of these are continuous, like pinches, and some, like the tap, are discrete. Drag a tap gesture recognizer to the scene, making sure you release over the MKMapView
object. You’ll see it does not become part of the view, but the view controller.

You can control the nature of the tap in the attributes. A double tap on a map is a map zoom gesture, so keep the default single tap and touch.
Close up the attributes inspector. Open the Assistant editor and make a action from the gesture recognizer to ViewController
. I’ll call it tapGesture.

Close the Assistant editor. Switch over to ViewController.swift
and find the tapGesture
method. Gesture recognizers fire for all kinds of reasons, so you have to pick the one you do your action. Type this:
if sender.state == .
You’ll see states that a tap can be.

For taps, you only care about when your finger leaves the device, since your finger might be moving before that. Select .ended
to make the best location for the tap.
if sender.state == .ended{ }
I’ve got a tap. I’ll find the location of the touch on a view with the gesture recognizer’s locationInview
method.
let locationInView = sender.location(in: mapView)
That requires a view. You have two choices here. You can use the sender’s view
, which will be the entire tappable area, or the mapView
. I’ll use the mapView
.
Location returns a CGPoint
in the view.
I’ll make that CGPoint
into a map coordinate of type CLLocationCoordinate2d
. There’s another method for that. MapKit includes a method convert
. Add this:
let tappedCoordinate = mapView.convert(locationInView , toCoordinateFrom: mapView)
convert
has two parameters. The first is the CGPoint
of the tapped point. The second is the view to use for the coordinate system. Generally this will be your map. I also match this to the view
in the location
method. You get the most accurate conversion that way.
I get a CLCoordinateLocation2D
from this which matches the tapped coordinate. With that coordinate, I’ll make an annotation with a method I already created.
addAnnotation(coordinate: tappedCoordinate)
Set your simulator for an iPhone 8 plus. Build and run this. Tap on the map and a marker appears. Tap again and another marker appears.

Tap outside the view and nothing happens. Clear removes the annotations.
Getting taps to map coordinates takes a few steps, but is not difficult. Your biggest challenge is to make sure you use the right views for getting the tap and the map coordinates.
This was a text version of the iOS Development Tips Weekly video series you can find at the Lynda.com and LinkedIn Learning libraries. Click the image at left to view.
The Whole Code
You’ll find the code below. You can also download the code from GitHub
// // ViewController.swift // MapTouch // // Created by Steven Lipton on 2/15/18. // Copyright © 2018 Steven Lipton. All rights reserved. // import UIKit import MapKit class ViewController: UIViewController,MKMapViewDelegate { //Two Rivers WI, the likely home of the Ice cream sundae let baseCoordinate = CLLocationCoordinate2DMake(44.1487225,-87.5684114) @IBOutlet weak var mapView: MKMapView! @IBAction func clearAnnotations(_ sender: UIButton) { mapView.removeAnnotations(mapView.annotations) } @IBAction func tapGesture(_ sender: UITapGestureRecognizer) { if sender.state == .ended{ let locationInView = sender.location(in: mapView) let tappedCoordinate = mapView.convert(locationInView, toCoordinateFrom: mapView) addAnnotation(coordinate: tappedCoordinate) } } func addAnnotation(coordinate:CLLocationCoordinate2D){ let annotation = MKPointAnnotation() annotation.coordinate = coordinate mapView.addAnnotation(annotation) } func setupMap(){ let region = MKCoordinateRegionMakeWithDistance(baseCoordinate, 500, 500) mapView.region = region } override func viewDidLoad() { super.viewDidLoad() setupMap() } }
Leave a Reply