【问题标题】:iOS Swift MapKit why MKPointAnnotation is draggable while a class that conforms MKAnnotation is notiOS Swift MapKit 为什么 MKPointAnnotation 是可拖动的,而符合 MKAnnotation 的类不是
【发布时间】:2016-12-04 10:03:25
【问题描述】:

我有一个类是 NSManagedObject 的子类,它符合 MKAnnotation,然后我在 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
    }
}

然后我将获取的对象添加到MapView,就像MKAnnotation 一样

self.MapView.addAnnotations(self.locations)

viewForAnnotation 中,我创建了MKAnnotationView 的子类,它有一个圆形的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 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)
}

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

【问题讨论】:

  • 在您的viewForAnnotation 中,您忘记分配annotationViewannotation。这需要是传入的annotation参数:annotationView.annotation = annotation

标签: ios swift mapkit draggable mkannotationview


【解决方案1】:

coordinate 属性随着拖动而改变,它必须是读/写的,因为它是一个没有设置器的计算属性,所以 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
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-28
    • 2016-07-12
    • 2011-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多