Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
631 views
in Technique[技术] by (71.8m points)

ios - Repeating pin annotation on map

I have just started learning Swift.

Question:

When I touch on map to place the pin annotation and drag my finger it creates repeating line of annotation.

enter image description here

import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {
    @IBOutlet weak var map: MKMapView!
    var manager:CLLocationManager!
    override func viewDidLoad() {
        super.viewDidLoad()
        //Manager for current location
        manager = CLLocationManager()
        manager.delegate = self
        manager.desiredAccuracy = kCLLocationAccuracyBest
        manager.requestWhenInUseAuthorization()
        manager.startUpdatingLocation()
        //Getting touch Gesture to add bookmark
        let uilpgr = UILongPressGestureRecognizer(target: self, action: "action:")
        uilpgr.minimumPressDuration = 1
        uilpgr.numberOfTouchesRequired = 1
        map.addGestureRecognizer(uilpgr)
    }
    func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        let userLocation:CLLocation = locations[0]
        let latitude:CLLocationDegrees = userLocation.coordinate.latitude
        let longitude:CLLocationDegrees = userLocation.coordinate.longitude
        let latDelta:CLLocationDegrees = 0.002
        let lonDelta:CLLocationDegrees = 0.002
        let span:MKCoordinateSpan = MKCoordinateSpanMake(latDelta, lonDelta)
        let location:CLLocationCoordinate2D = CLLocationCoordinate2DMake(latitude, longitude)
        let region:MKCoordinateRegion = MKCoordinateRegionMake(location, span)
        map.setRegion(region, animated: true)
    }
    func action(gestureRecognizer: UIGestureRecognizer) {
        let touchPoint = gestureRecognizer.locationInView(self.map)
        let newCoordinate: CLLocationCoordinate2D = map.convertPoint(touchPoint, toCoordinateFromView: self.map)
        print(newCoordinate)
        let annotation = MKPointAnnotation()
        annotation.coordinate = newCoordinate
        annotation.title = "New Place"
        annotation.subtitle = "One day I'll go here..."
        map.addAnnotation(annotation)
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Xcode 8.2 ? Swift 3.0.2

You just need to check the gesture recognizer state and make sure if not .Began return. Just add this if condition at the top of your action method:

func action(_ gestureRecognizer: UIGestureRecognizer) {

    if gestureRecognizer.state != UIGestureRecognizerState.began {
        return
    }

    //  your code

If you would like to allow the user to move the pin while touching you will need to switch the gesture recognizer state and update the annotation coordinate if gestureRecognizer.state changes:

func action(_ gestureRecognizer: UIGestureRecognizer) {
    switch gestureRecognizer.state {
    case .began:
        let annotation = MKPointAnnotation()
        annotation.coordinate = mapView.convert(gestureRecognizer.location(in: mapView), toCoordinateFrom: mapView)
        annotation.title =  "Untitled"
        mapView.addAnnotation(annotation)
    case .changed:
        if let annotation = (mapView.annotations.filter{$0.title! == "Untitled" }).first as? MKPointAnnotation {
            annotation.coordinate =  mapView.convert(gestureRecognizer.location(in: mapView), toCoordinateFrom: mapView)
        }
    case .cancelled:
        if let annotation = (mapView.annotations.filter{$0.title! == "Untitled" }).first as? MKPointAnnotation {
            mapView.removeAnnotation(annotation)
        }
    // you can also prompt the user here for the annotation title
    case .ended:
        if let annotation = (mapView.annotations.filter{$0.title! == "Untitled" }).first as? MKPointAnnotation {
            let alert = UIAlertController(title: "New Annotation", message: "", preferredStyle: .alert)
            var inputTextField: UITextField?
            alert.addAction(UIAlertAction(title: "Add", style: .default) { _ in
                if  let annotationTitle = inputTextField?.text {
                    annotation.title =  annotationTitle
                    annotation.subtitle = "Lat:(String(format: "%.06f", annotation.coordinate.latitude))  Lon:(String(format: "%.06f", annotation.coordinate.longitude))"
                }
            })
            alert.addTextField(configurationHandler: { textField in
                textField.placeholder = "Place Description"
                inputTextField = textField
            })
            alert.addAction(UIAlertAction(title: "Cancel", style: .cancel){ _ in
                self.mapView.removeAnnotation(annotation)
            })
            present(alert, animated: true, completion: nil)
        }
    default:
        print("default")
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...