I have been trying to put a draggable annotation on a mapview for ages. (I'm using the default pin, not my own) So far I can only display it at set coordinates (not much of an achievement, really) and I need to get the annotation first of all to react to being selected, it doesn't ever get received by the didChangeDragState
func. Then I need to be able to drag it, place it in a new location and get the coordinates of the new location.
I'm reasonably new to Swift, but I've taken on a rather difficult project.
I've looked at pretty much everything I could find on google looking for "draggable MKAnnotation
mapkit in Swift" and similar variants.(edit: I hadn't found any answers that shed light on my problem, where all other answers gave responses for how to upload a personalized MKAnnotation
. They all had title fields, but none of the answers mentioned that a title field was necessary, which turned out to be the main problem. They only mentioned that I should set the dragState to control the movement of the pin, but this turned out to be incorrect in my case as you see below) ANYWAY!
Below is my code where I try to implement the mapView and add an annotation.
var currentLat:CLLocationDegrees!
var currentLong:CLLocationDegrees!
var currentCoordinate:CLLocationCoordinate2D!
....
override func viewDidAppear(animated: Bool) {
let annotation = PinAnnotationClass()
annotation.setCoordinate(currentCoordinate)
//annotation.setCoordinate(currentCoordinate)
//AnnotationView()
self.mapView.addAnnotation(annotation)
}
override func viewDidLoad() {
super.viewDidLoad()
println("hello!")
self.mapView.delegate = self
loadMap()
findPath()
}
func loadMap()
{
currentCoordinate = CLLocationCoordinate2DMake(currentLat, currentLong)
var mapSpan = MKCoordinateSpanMake(0.01, 0.01)
var mapRegion = MKCoordinateRegionMake(currentCoordinate, mapSpan)
self.mapView.setRegion(mapRegion, animated: true)
}
Along with extension:
extension DetailsViewController: MKMapViewDelegate {
func mapView(mapView: MKMapView!,
viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! {
if annotation is MKUserLocation {
//return nil so map view draws "blue dot" for standard user location
return nil
}
let reuseId = "pin"
var pinView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId) as? MKPinAnnotationView
if pinView == nil {
pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
pinView!.canShowCallout = true
pinView!.draggable = true
pinView!.annotation.coordinate
pinView!.animatesDrop = true
pinView!.pinColor = .Green
}
else {
pinView!.annotation = annotation
}
return pinView
}
func mapView(mapView: MKMapView!, annotationView view: MKAnnotationView!, didChangeDragState newState: MKAnnotationViewDragState, fromOldState oldState: MKAnnotationViewDragState) {
if (newState == MKAnnotationViewDragState.Starting) {
view.dragState = MKAnnotationViewDragState.Dragging
} else if (newState == MKAnnotationViewDragState.Ending || newState == MKAnnotationViewDragState.Canceling){
view.dragState = MKAnnotationViewDragState.None
}
}
func mapView(mapView: MKMapView!, annotationView view: MKAnnotationView!, calloutAccessoryControlTapped control: UIControl!) {
if let annotation = view.annotation as? PinAnnotationClass{
}
}
I also have a custom PinAnnotation class:
import Foundation
import MapKit
class PinAnnotationClass : NSObject, MKAnnotation {
private var coord: CLLocationCoordinate2D = CLLocationCoordinate2D(latitude: 0, longitude: 0)
var coordinate: CLLocationCoordinate2D {
get {
return coord
}
}
var title: String = ""
var subtitle: String = ""
func setCoordinate(newCoordinate: CLLocationCoordinate2D) {
self.coord = newCoordinate
}