2

What I did so far was create a map. Then show user location and center it so that map is centered when travelling (car etc)

But now I would like to add a long press gesture so that If a user does the input a pin will be dropped. I have struggled with tutorials and the simulator crashes.

How would I add longPressGesturerecognizer so that it drops a pin on my mapView.

Here is my code-

import UIKit
import MapKit
import CoreLocation

class Page2: UIViewController, MKMapViewDelegate,  CLLocationManagerDelegate{

    @IBOutlet var mapView: MKMapView!
    let locationManager = CLLocationManager()

    override func viewDidLoad() {
        super.viewDidLoad()
        self.locationManager.delegate = self
        self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
        self.locationManager.requestWhenInUseAuthorization()
        self.locationManager.startUpdatingLocation()
        //blue dot on the map
        self.mapView.showsUserLocation = true
        //tracking mode on
        self.mapView.userTrackingMode = .follow
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    // location Manager Delegate center user on map
    private func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {

        let location = locations.last
        let center = CLLocationCoordinate2D(latitude: location!.coordinate.latitude, longitude: (location?.coordinate.longitude)!)
        let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.005, longitudeDelta: 0.005)) //zoom on map
        self.mapView.setRegion(region, animated: true)
        self.locationManager.stopUpdatingLocation()
    }

    // print errors
    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error){
        print("Errors: " + error.localizedDescription)
    }
}
Nirav D
  • 71,513
  • 12
  • 161
  • 183
sabrefm1
  • 61
  • 1
  • 9

3 Answers3

8

First of all in Swift 3 signature of CLLocationManagerDelegate method's locationManager(_:didUpdateLocations:) is changed, so you need to change that method as follow.

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
     //your code and don't forgot to remove private
}

You can use longGesture with mapView like this, first addGestureRecognizer in your mapView in the viewDidLoad.

let longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(addAnnotationOnLongPress(gesture:)))
longPressGesture.minimumPressDuration = 1.0
self.mapView.addGestureRecognizer(longPressGesture)

Now add action for that UILongPressGestureRecognizer.

@objc func addAnnotationOnLongPress(gesture: UILongPressGestureRecognizer) {

    if gesture.state == .ended {
        let point = gesture.location(in: self.mapView)
        let coordinate = self.mapView.convert(point, toCoordinateFrom: self.mapView)
        print(coordinate)
        //Now use this coordinate to add annotation on map.
        var annotation = MKPointAnnotation()
        annotation.coordinate = coordinate
        //Set title and subtitle if you want
        annotation.title = "Title" 
        annotation.subtitle = "subtitle" 
        self.mapView.addAnnotation(annotation)
    }
}
Nirav D
  • 71,513
  • 12
  • 161
  • 183
  • thanks I seem to be geting this error on this line let longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(addAnnotationOnLongPress(gesture:))) use of local variable 'addAnnotationOnLongPress(gesture:)' before its declaration – sabrefm1 Nov 28 '16 at 13:10
  • Only thing is see now is that the coordinates are recorded in the output but its not dropping any pins – sabrefm1 Nov 28 '16 at 13:21
  • this part here ? //Now use this coordinate to add annotation on map. – sabrefm1 Nov 28 '16 at 13:38
  • thanks for the help I have an error on this last line self.mapView.addAnnotation(myHomePin) error: use of unresolved identifer 'myHomePin' will try and figure this out – sabrefm1 Nov 28 '16 at 13:59
  • @sabrefm1 It was typo mistake check the edit answer :) – Nirav D Nov 28 '16 at 14:01
1

You can also use tap gesture for drop pin.

Add tap gesture

    let tapGesture = UITapGestureRecognizer(target: self, action:#selector(AddressViewController.handleTap(_:)))
    tapGesture.delegate = self
    mapView.addGestureRecognizer(tapGesture)

drop pin on gesture

func handleTap(_ sender: UIGestureRecognizer)
{
  if sender.state == UIGestureRecognizerState.ended {

        let touchPoint = sender.location(in: mapView)
        let touchCoordinate = mapView.convert(touchPoint, toCoordinateFrom: mapView)
        let annotation = MKPointAnnotation()
        annotation.coordinate = touchCoordinate
        annotation.title = "Event place"
        mapView.removeAnnotations(mapView.annotations)
    mapView.addAnnotation(annotation) //drops the pin
  }
}
  • @RohirParsana excellent answer. But how do I get the Latitude and Longitude? I want to put these into variables. best, Philip Just got it :-) touchCoordinate returns latitude and longitude. I can get these separately e.g. print(touchCoordinate.latitude) – PhilipS Mar 06 '17 at 11:35
1

I think this updated little code help other to implement annotation with put pin in long press:

    import UIKit
    import MapKit
    class ViewController: UIViewController, MKMapViewDelegate {

        @IBOutlet weak var map: MKMapView!

        override func viewDidLoad() {
            super.viewDidLoad()

            let uilpgr = UILongPressGestureRecognizer(target: self, action: #selector(longPressed(gestureRecognized:)))

            //long press (2 sec duration)
            uilpgr.minimumPressDuration = 2
            map.addGestureRecognizer(uilpgr)   
        }

        func longPressed(gestureRecognized: UIGestureRecognizer){
            let touchpoint = gestureRecognized.location(in: self.map)
            let location = map.convert(touchpoint, toCoordinateFrom: self.map)

            let annotation = MKPointAnnotation()
            annotation.title = "Latitude: \(location.latitude)"
            annotation.subtitle = "Longitude: \(location.longitude)"
            annotation.coordinate = location
            map.addAnnotation(annotation)


        }

        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }


    }
Mahmudur Rahman
  • 638
  • 9
  • 25