iOS : Swift - How to add pinpoint to map on touch and get detailed address of that location?
To react to the touch on map you need to set up a tap recogniser for the mapView
in viewDidLoad
:
let gestureRecognizer = UITapGestureRecognizer( target: self, action:#selector(handleTap)) gestureRecognizer.delegate = self mapView.addGestureRecognizer(gestureRecognizer)
Handle the tap and get the tapped location coordinates:
func handleTap(gestureRecognizer: UITapGestureRecognizer) { let location = gestureRecognizer.location(in: mapView) let coordinate = mapView.convert(location, toCoordinateFrom: mapView) // Add annotation: let annotation = MKPointAnnotation() annotation.coordinate = coordinate mapView.addAnnotation(annotation)}
Now you only have to implement the MKMapView delegate functions to draw the annotations. A simple google search should get you the rest of that.
Here is a working Xcode 10.1, Swift 4.2 project with MapKit delegates to control the annotations (pin color, pin image etc.) and delegate to handle a click on the added annotation:Github Project
import UIKitimport MapKitclass ViewController: UIViewController {@IBOutlet weak var mapView: MKMapView!override func viewDidLoad() { super.viewDidLoad() mapView.delegate = self let longTapGesture = UILongPressGestureRecognizer(target: self, action: #selector(longTap)) mapView.addGestureRecognizer(longTapGesture)}@objc func longTap(sender: UIGestureRecognizer){ print("long tap") if sender.state == .began { let locationInView = sender.location(in: mapView) let locationOnMap = mapView.convert(locationInView, toCoordinateFrom: mapView) addAnnotation(location: locationOnMap) }}func addAnnotation(location: CLLocationCoordinate2D){ let annotation = MKPointAnnotation() annotation.coordinate = location annotation.title = "Some Title" annotation.subtitle = "Some Subtitle" self.mapView.addAnnotation(annotation)}}extension ViewController: MKMapViewDelegate{func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { guard annotation is MKPointAnnotation else { print("no mkpointannotaions"); return nil } let reuseId = "pin" var pinView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseId) as? MKPinAnnotationView if pinView == nil { pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId) pinView!.canShowCallout = true pinView!.rightCalloutAccessoryView = UIButton(type: .infoDark) pinView!.pinTintColor = UIColor.black } else { pinView!.annotation = annotation } return pinView}func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) { print("tapped on pin ")}func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) { if control == view.rightCalloutAccessoryView { if let doSomething = view.annotation?.title! { print("do something") } } }}
Swift 4:
@IBOutlet weak var mapView: MKMapView! func handleLongPress (gestureRecognizer: UILongPressGestureRecognizer) { if gestureRecognizer.state == UIGestureRecognizerState.began { let touchPoint: CGPoint = gestureRecognizer.location(in: mapView) let newCoordinate: CLLocationCoordinate2D = mapView.convert(touchPoint, toCoordinateFrom: mapView) addAnnotationOnLocation(pointedCoordinate: newCoordinate) }}func addAnnotationOnLocation(pointedCoordinate: CLLocationCoordinate2D { let annotation = MKPointAnnotation() annotation.coordinate = pointedCoordinate annotation.title = "Loading..." annotation.subtitle = "Loading..." mapView.addAnnotation(annotation)}