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
}
}
我有一个 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
}
}