简体   繁体   中英

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

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 then add the fetched objects to the MapView as MKAnnotation like that

self.MapView.addAnnotations(self.locations)

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

}

then I set the annotationView to be draggable in the 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
 }

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

* The solution that i don't like *

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
    }

}

and then for adding it to the 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?

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

* here is the solution *

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM