iOS Swift MapKit 为什么 MKPointAnnotation 是可拖动的,而符合 MKAnnotation 的 class 不是

iOS Swift MapKit why MKPointAnnotation is draggable while a class that conforms MKAnnotation is not

我有一个 class,它是符合 MKAnnotation 的 NSManagedObject 的子class,然后我在 MapView 中使用它,使某些位置从 CoreData

class Location: NSManagedObject , MKAnnotation {

    var coordinate : CLLocationCoordinate2D {
        return CLLocationCoordinate2D(latitude: Double(self.latitude), longitude: Double(self.longitude))
    }

    var title: String? {
        return self.name
    }

    var subtitle: String? {
        return self.category
    }
}

然后我将获取的 objects 添加到 MapView 中作为 MKAnnotation 就像那样

self.MapView.addAnnotations(self.locations)

并且在 viewForAnnotation 中,我制作了 MKAnnotationView 的一个子 class,它有一个圆形的 imageView

class AMKAnnotationView: MKAnnotationView {

    var imageView = UIImageView()

    init(annotation: MKAnnotation?, reuseIdentifier: String?, size: CGSize) {
        super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
        self.frame = CGRectMake(0, 0, size.width, size.height)
        self.commonInit()
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
    }

    required init?(coder: NSCoder) {
        super.init(coder: coder)
    }

    func commonInit() {
        self.imageView.frame = CGRectMake(0, 0, self.frame.width, self.frame.height)
        self.imageView.layer.masksToBounds = true
        self.imageView.layer.cornerRadius = self.imageView.frame.height/2
        self.imageView.layer.borderWidth = 5.0
        self.imageView.layer.borderColor = UIColor.whiteColor().CGColor
        self.imageView.userInteractionEnabled = false
        self.addSubview(imageView)
        self.sendSubviewToBack(self.imageView)
    }

}

然后我在 viewForAnnotation

中将 annotationView 设置为 draggable
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {

        var annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier("pin") as? AMKAnnotationView

        if annotationView == nil {
            annotationView = AMKAnnotationView(annotation: annotation, reuseIdentifier: "pin", size: CGSizeMake(65, 65))
            annotationView?.draggable = true
            annotationView?.canShowCallout = true

            let index = ... // i get the index
            let location = ... // i get the current location

            annotationView?.imageView.image = UIImage(named: "No Photo")

        }

        return annotationView
 }

要使 annotationView 成为 draggable 我们应该实现 didChangeDragState 委托方法

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

        switch newState {
        case .Starting:
            view.dragState = .Dragging
        case .Ending, .Canceling:
            view.dragState = .None
             // then i save the changes to CoreData           
            }
        default: break
        }
}

如果我尝试在地图上拖动注释,它不起作用

* 我不喜欢的解决方案 *

根据这个问题的标题,我的工作方式是使用 MKPointAnnotation,我的意思是每次我向地图添加注释时,我都会转换为 MKPointAnnotation这让我制作了 MKPointAnnotation 的另一个子 class 以便我可以跟踪位置

class AMKPointAnnotation : MKPointAnnotation {

    var location : Location!

    init(location:Location) {
        super.init()
        self.location = location
        self.title = location.title
        self.subtitle = location.subtitle
        self.coordinate = location.coordinate
    }

}

然后将其添加到 MapView

for location in self.locations {
                    let pointAnnotation = AMKPointAnnotation(location: location)
                    self.MapView.addAnnotation(pointAnnotation)
}

有人试过吗?我做错了什么?

coordinate 属性 随着拖动而改变,它必须是 read/write 并且因为它是一个没有 setter 的计算 属性 MapKit 阻止了拖那个

* 这是解决方案 *

class Location: NSManagedObject , MKAnnotation {

var coordinate : CLLocationCoordinate2D {
     set {
          self.latitude = newValue.latitude
          self.longitude = newValue.longitude
        }
      get {
          return CLLocationCoordinate2D(latitude: Double(self.latitude), longitude: Double(self.longitude))
        }
    }

    var title: String? {
        return self.name
    }

    var subtitle: String? {
        return self.category
    }
}