Search code examples
iosswiftannotationsmkmapview

Swift 3.0 Placing a Annotation On MapView


I have my code set up such that a long press on the mapView will allow the user to drop a pin. I was wondering if there was a way that could allow the user to type in a title for the annotation, that way after pressing the annotation (once the pin is placed), the title would show up.

var locationManager = CLLocationManager()

override func viewDidLoad() {
    super.viewDidLoad()
    mapView.delegate = self
    let mapPress = UILongPressGestureRecognizer(target: self, action: #selector(AddressVC.addAnnotation(_:)))
    mapPress.minimumPressDuration = 1.5
    mapView.addGestureRecognizer(mapPress)
    }

func addAnnotation(_ recognizer: UIGestureRecognizer){
    let annotations = self.mapView.annotations
    self.mapView.removeAnnotations(annotations)
    let touchedAt = recognizer.location(in: self.mapView) // adds the location on the view it was pressed
    let newCoordinates : CLLocationCoordinate2D = mapView.convert(touchedAt, toCoordinateFrom: self.mapView) // will get coordinates

    let annotation = MKPointAnnotation()
    annotation.coordinate = newCoordinates
    self.mapView.addAnnotation(annotation)
}

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
    if (annotation is MKUserLocation) {
        //if annotation is not an MKPointAnnotation (eg. MKUserLocation),
        return nil
    }
    let identifier = "pinAnnotation"
    if let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) {
        annotationView.annotation = annotation
        return annotationView
    } else {
        let annotationView = MKPinAnnotationView(annotation:annotation, reuseIdentifier: identifier)
        annotationView.isEnabled = true
        annotationView.canShowCallout = true

        return annotationView
    }
}

Solution

  • I suggest using an UIAlertController with a UITextField for the user to enter a name.

    import UIKit
    import MapKit
    
    class ViewController: UIViewController {
    
        @IBOutlet weak var map: MKMapView!
    
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view, typically from a nib.
    
            let tap = UILongPressGestureRecognizer(target: self, action: #selector(self.createAnnotation))
    
            self.map.addGestureRecognizer(tap)
        }
    
        func createAnnotation(gesture: UILongPressGestureRecognizer){
    
            if gesture.state == .began {
    
                let point = gesture.location(in: self.map)
    
                let coordinate = self.map.convert(point, toCoordinateFrom: nil)
    
                let alertVC = UIAlertController(title: "Create Pin", message: "Enter a title for your pin.", preferredStyle: .alert)
    
                alertVC.addTextField { (textfield) in
    
                    textfield.placeholder = "Enter a Title"
    
                    textfield.autocapitalizationType = .words
                }
    
                alertVC.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
    
                alertVC.addAction(UIAlertAction(title: "Create", style: .default, handler: { (action) in
    
                    guard
    
                        let textfield = alertVC.textFields?.first,
    
                        let text = textfield.text
    
                        else {
    
                            return
                    }
    
                    let pin = MKPointAnnotation()
    
                    pin.title = text
    
                    pin.coordinate = coordinate
    
                    self.map.addAnnotation(pin)
                }))
    
                self.present(alertVC, animated: true, completion: nil)
            }
        }
    }
    

    Screenshot of UIAlertController