Said Alır
Said Alır

Reputation: 170

How to let user to add custom annotation?

I could not found any document, video or stackoverflow answer.

Here is my problem. I created map and add into my custom MKAnnotation and MKAnnotationView.

I want to let user to create custom pin and save to it's local via CoreData

MyCustomAnnotation has same attributes which is title, subtitle, and coordinate.

The first solution that I come up with put a button which creates a draggable pin to user location.

But I need to get less complex, more sophistication solution.

private func addPins() {
    let list = PrivateLocations.shared.initLocations()
    for pin in list {
        map.addAnnotation(pin)
    }
}

    func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {

    if view.annotation is MKUserLocation { return }
    let views = Bundle.main.loadNibNamed("CustomCalloutView", owner: nil, options: nil)
    let customView = views?[0] as! CustomCalloutView
    customView.delegate = self
    customView.isUserInteractionEnabled = true
    customView.titleLabel.text = view.annotation?.title!
    customView.desc.text = view.annotation?.subtitle!
    customView.center = CGPoint(x: view.bounds.size.width / 2, y: -customView.bounds.size.height*0.52)
    view.addSubview(customView)
    map.setCenter((view.annotation?.coordinate)!, animated: true)
}

    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {

    if annotation is MKUserLocation {
        return nil
    } else {
        let annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: "CustomAnnotationView")
        annotationView.image = UIImage(named: "myImage")
        annotationView.canShowCallout = false
        return annotationView
    }
}

And finally here is my CustomPin class :

var coordinate: CLLocationCoordinate2D
var title: String?
var subtitle: String?

init(_ title: String, _ subtitle: String, _ coordinate: CLLocationCoordinate2D) {
    self.title = title
    self.subtitle = subtitle
    self.coordinate = coordinate
}

Upvotes: 0

Views: 372

Answers (1)

Said Alır
Said Alır

Reputation: 170

That's how I solve this problem,

1) Create a UIView for user show where he wants to add an annotation.

2) Add a pan gesture recognizer in it.

func addPanGesture(view: UIView) {
    let pan = UIPanGestureRecognizer(target: self, action: #selector (self.handlePan(sender:)))
    view.addGestureRecognizer(pan)
}

3) In my selector func, I call pinDropped() func

  @objc func handlePan(sender: UIPanGestureRecognizer) {

    let view = sender.view!
    let translation = sender.translation(in: self.mapView)

    switch sender.state {
    case .began, .changed:
        pinImage.center = CGPoint(x: dropPinImage.center.x + translation.x, y: dropPinImage.center.y + translation.y)
        sender.setTranslation(CGPoint.zero, in: view)
        break
    default:
        pinDropped()
        break
    }
}

4) I write what will be happening in my pinDropped func

func pinDropped() {
    DispatchQueue.main.async {
        let pin = CustomPin(self.lastOrigin, "pin")
        self.mapView.addAnnotation(pin)
    }
    self.saveButton.alpha = 1
    pinImage.alpha = 0
}

Upvotes: 0

Related Questions