Ios 即使设置为可拖动,MKAnnotation Pin也不会拖动

Ios 即使设置为可拖动,MKAnnotation Pin也不会拖动,ios,swift,mkmapview,mkpinannotationview,mkmapviewdelegate,Ios,Swift,Mkmapview,Mkpinannotationview,Mkmapviewdelegate,多年来,我一直试图在地图视图上添加可拖动的注释。我使用的是默认pin,不是我自己的,到目前为止,我只能在设置的坐标上显示它,这不是一个很大的成就,我真的需要首先得到注释以对被选中做出反应,它永远不会被didChangeDragState函数接收到。然后我需要能够拖动它,把它放在一个新的位置,并获得新位置的坐标 我对斯威夫特相当陌生,但我承担了一个相当困难的项目。 我在谷歌上找到了几乎所有我能找到的东西,在Swift和类似的变体中寻找可拖动的MKAnnotation mapkit。编辑:我没有找到

多年来,我一直试图在地图视图上添加可拖动的注释。我使用的是默认pin,不是我自己的,到目前为止,我只能在设置的坐标上显示它,这不是一个很大的成就,我真的需要首先得到注释以对被选中做出反应,它永远不会被didChangeDragState函数接收到。然后我需要能够拖动它,把它放在一个新的位置,并获得新位置的坐标

我对斯威夫特相当陌生,但我承担了一个相当困难的项目。 我在谷歌上找到了几乎所有我能找到的东西,在Swift和类似的变体中寻找可拖动的MKAnnotation mapkit。编辑:我没有找到任何能说明我的问题的答案,所有其他答案都给出了如何上传个性化MKAnnotation的答案。他们都有标题字段,但没有一个答案提到标题字段是必要的,这是主要问题。他们只提到我应该设置dragState来控制销的移动,但这在我的情况下是不正确的,正如您在下面看到的一样! 下面是我尝试实现mapView并添加注释的代码

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)
}
随着扩展:

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{
    }
}
我还有一个自定义的PinAnnotation类:

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
}

最初的问题是注释的标题没有设置

如果未设置批注的标题,则无法将其设置为选定状态,并且不会显示详图索引,并且不会调用didSelectAnnotationView

由于要拖动批注,必须首先选择它,因此如果未设置标题,则无法拖动它

因此,在创建注释时,请将其标题设置为:

let annotation = PinAnnotationClass()
annotation.title = "hello"
annotation.setCoordinate(currentCoordinate)
这至少可以让您开始拖动它,但由于您使用的是MKPinAnnotationView而不是普通的MKAnnotationView,因此不需要实现didChangeDragState。事实上,如果您在使用MKPinAnnotationView时实现了它,则注释将无法正确拖动

在didChangeDragState中,删除设置view.dragState的代码-使用MKPinAnnotationView时不需要它

相反,您可以只记录删除注释的坐标:

func mapView(mapView: MKMapView!, annotationView view: MKAnnotationView!, didChangeDragState newState: MKAnnotationViewDragState, fromOldState oldState: MKAnnotationViewDragState) {

    if newState == MKAnnotationViewDragState.Ending {
        let ann = view.annotation
        print("annotation dropped at: \(ann!.coordinate.latitude),\(ann!.coordinate.longitude)")
    }
}
不相关,但PinAnnotationClass实现比需要的更复杂。您不需要为坐标编写显式的get和set方法。只需声明坐标,即可完成getter/setter:

class PinAnnotationClass : NSObject, MKAnnotation {
    var title: String = ""
    var subtitle: String = ""
    var coordinate: CLLocationCoordinate2D = kCLLocationCoordinate2DInvalid
    //kCLLocationCoordinate2DInvalid is a pre-defined constant
    //better than using "0,0" which are technically valid
}
您还需要更改坐标的指定方式:

//annotation.setCoordinate(currentCoordinate)  //old
annotation.coordinate = currentCoordinate      //new
最后,也不相关,但这一行在viewForAnnotation中


意味着什么也不做,请将其删除。

可能是重复的。我原以为我也有同样的问题,但结果证明我只是没有接触到正确的拖动位置。看起来要拖动的位置是非常有限的销底部,而不是销头。嘿,安娜,非常感谢!我在其他帖子上看到了你的评论,你太棒了!我应该编辑我上面的帖子以反映您的更改,还是应该让有类似问题的人看到我的问题然后再看您的答案?谢谢,请留下问题的原始代码作为参考。如果问题中的代码被更改,答案看起来很奇怪,因为现在代码已经工作了。接受答案表明这些改变对你有效。但是,如果您愿意,您可以将更新后的代码添加到您的帖子中,同时显示之前和之后的内容,但这通常不会完成。。。PinAnnotationClass中的坐标属性必须是var。在我的例子中,我将其声明为let坐标,直到我将其更改为var,它才起作用。@Anna Thank效果很好,我拔了一些头发,直到我找到这个:再次感谢
pinView!.annotation.coordinate