而符合MKAnnotation的类却无法拖动

而符合MKAnnotation的类却无法拖动

本文介绍了iOS Swift MapKit为什么MKPointAnnotation是可拖动的,而符合MKAnnotation的类却无法拖动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类,它是符合MKAnnotation的NSManagedObject的子类,然后在MapView中使用它来从CoreData

i have a class that is a subclass of NSManagedObject that conform to MKAnnotation and then i use that in a MapView that dequeues some locations from 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
    }
}

i然后像这样MKAnnotation将获取的对象添加到MapView

i then add the fetched objects to the MapView as MKAnnotation like that

self.MapView.addAnnotations(self.locations)

,然后在viewForAnnotation中,我做了一个MKAnnotationView的子类,该子类具有一个舍入的imageView

and in the viewForAnnotation i made a subclass of MKAnnotationView that has a rounded 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

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委托方法

to make the annotationView to be draggable we should implement the didChangeDragState delegate method

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
        }
}

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

if i try to drag the annotation on the map it doesn't work

*我不喜欢的解决方案*

我得到这个问题的标题的方式是使用MKPointAnnotation,我的意思是每次我在地图上添加注解并转换为MKPointAnnotation时,都会使我成为另一个子类MKPointAnnotation的位置,以便我可以跟踪位置

The way i got it work as of the title of this question says is to use MKPointAnnotation and i mean by that is each time i add an annotation to the map i convert to MKPointAnnotation which made me make another subclass of MKPointAnnotation so that i can keep track of the location

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)
}

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

any one tried it before ? What am I doing wrong?

推荐答案

coordinate属性随拖动而变化,并且必须是可读写的,并且由于它是没有设置器的计算属性,因此MapKit阻止了该拖动

The coordinate property changes with dragging and it must be read/write and since it was a computed property with no setter the MapKit prevented the dragging for that

*这是解决方法*

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
    }
}

这篇关于iOS Swift MapKit为什么MKPointAnnotation是可拖动的,而符合MKAnnotation的类却无法拖动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-06 04:35