MKAnnotation Pin 不会拖动,即使设置为可拖动
MKAnnotation Pin won't drag, even though set as draggable
多年来,我一直在尝试在地图视图上添加可拖动的注释。 (我使用的是默认图钉,不是我自己的)到目前为止,我只能在设定的坐标上显示它(真的不是什么成就),我需要首先获得注释才能对被选中做出反应,它不会永远不会被 didChangeDragState
函数接收。然后我需要能够拖动它,将它放在一个新位置并获取新位置的坐标。
我是 Swift 的新手,但我已经完成了一个相当困难的项目。
我已经查看了几乎所有我能在 google 上找到的所有内容,寻找 "draggable MKAnnotation
mapkit in Swift" 和类似的变体。(编辑:我没有找到任何可以阐明我的问题的答案,其中所有其他答案都给出了如何上传个性化 MKAnnotation
的回复。他们都有标题字段,但 none 的答案提到标题字段是必要的,结果证明这是主要问题。他们只提到我应该设置 dragState 来控制图钉的移动,但结果证明在我的情况下这是不正确的,如下所示) 无论如何!
下面是我尝试实现 mapView 并添加注释的代码。
var currentLat:CLLocationDegrees!
var currentLong:CLLocationDegrees!
var currentCoordinate:CLLocationCoordinate2D!
....
override func viewDidAppear(animated: Bool) {
let annotation = PinAnnotationClass()
annotation.setCoordinate(currentCoordinate)
//annotation.setCoordinate(currentCoordinate)
//AnnotationView()
self.mapView.addAnnotation(annotation)
}
override func viewDidLoad() {
super.viewDidLoad()
println("hello!")
self.mapView.delegate = self
loadMap()
findPath()
}
func loadMap()
{
currentCoordinate = CLLocationCoordinate2DMake(currentLat, currentLong)
var mapSpan = MKCoordinateSpanMake(0.01, 0.01)
var mapRegion = MKCoordinateRegionMake(currentCoordinate, mapSpan)
self.mapView.setRegion(mapRegion, animated: true)
}
连同扩展名:
extension DetailsViewController: MKMapViewDelegate {
func mapView(mapView: MKMapView!,
viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! {
if annotation is MKUserLocation {
//return nil so map view draws "blue dot" for standard user location
return nil
}
let reuseId = "pin"
var pinView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId) as? MKPinAnnotationView
if pinView == nil {
pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
pinView!.canShowCallout = true
pinView!.draggable = true
pinView!.annotation.coordinate
pinView!.animatesDrop = true
pinView!.pinColor = .Green
}
else {
pinView!.annotation = annotation
}
return pinView
}
func mapView(mapView: MKMapView!, annotationView view: MKAnnotationView!, didChangeDragState newState: MKAnnotationViewDragState, fromOldState oldState: MKAnnotationViewDragState) {
if (newState == MKAnnotationViewDragState.Starting) {
view.dragState = MKAnnotationViewDragState.Dragging
} else if (newState == MKAnnotationViewDragState.Ending || newState == MKAnnotationViewDragState.Canceling){
view.dragState = MKAnnotationViewDragState.None
}
}
func mapView(mapView: MKMapView!, annotationView view: MKAnnotationView!, calloutAccessoryControlTapped control: UIControl!) {
if let annotation = view.annotation as? PinAnnotationClass{
}
}
我还有一个自定义 PinAnnotation class:
import Foundation
import MapKit
class PinAnnotationClass : NSObject, MKAnnotation {
private var coord: CLLocationCoordinate2D = CLLocationCoordinate2D(latitude: 0, longitude: 0)
var coordinate: CLLocationCoordinate2D {
get {
return coord
}
}
var title: String = ""
var subtitle: String = ""
func setCoordinate(newCoordinate: CLLocationCoordinate2D) {
self.coord = newCoordinate
}
最初的问题是注释的 title
没有设置。
如果未设置注释的 title
,则无法将其设置为 "selected" 状态,并且不会显示标注并且 didSelectAnnotationView
不会被调用。
因为要拖动注释,必须先select,没有title
就不能拖动设置。
因此,在创建注释时,将其 title
设置为:
let annotation = PinAnnotationClass()
annotation.title = "hello"
annotation.setCoordinate(currentCoordinate)
这至少应该让你开始拖动它,但由于你使用的是 MKPinAnnotationView
而不是普通的 MKAnnotationView
,你做 not 需要实施 didChangeDragState
。事实上,如果你在使用 MKPinAnnotationView
时实现它,注释将无法正确拖动。
在 didChangeDragState
中,删除设置 view.dragState
的代码——使用 MKPinAnnotationView
时不需要它。
相反,您可以只记录放置注释的坐标:
func mapView(mapView: MKMapView!, annotationView view: MKAnnotationView!, didChangeDragState newState: MKAnnotationViewDragState, fromOldState oldState: MKAnnotationViewDragState) {
if newState == MKAnnotationViewDragState.Ending {
let ann = view.annotation
print("annotation dropped at: \(ann!.coordinate.latitude),\(ann!.coordinate.longitude)")
}
}
不相关,但是 PinAnnotationClass
实现比它需要的更复杂。您不需要为 coordinate
编写显式的获取和设置方法。只需声明 coordinate
,getter/setter 将为您完成:
class PinAnnotationClass : NSObject, MKAnnotation {
var title: String = ""
var subtitle: String = ""
var coordinate: CLLocationCoordinate2D = kCLLocationCoordinate2DInvalid
//kCLLocationCoordinate2DInvalid is a pre-defined constant
//better than using "0,0" which are technically valid
}
您还需要更改坐标的分配方式:
//annotation.setCoordinate(currentCoordinate) //old
annotation.coordinate = currentCoordinate //new
最后,也无关,但是 viewForAnnotation
中的这一行
pinView!.annotation.coordinate
表示什么都不做,去掉。
多年来,我一直在尝试在地图视图上添加可拖动的注释。 (我使用的是默认图钉,不是我自己的)到目前为止,我只能在设定的坐标上显示它(真的不是什么成就),我需要首先获得注释才能对被选中做出反应,它不会永远不会被 didChangeDragState
函数接收。然后我需要能够拖动它,将它放在一个新位置并获取新位置的坐标。
我是 Swift 的新手,但我已经完成了一个相当困难的项目。
我已经查看了几乎所有我能在 google 上找到的所有内容,寻找 "draggable MKAnnotation
mapkit in Swift" 和类似的变体。(编辑:我没有找到任何可以阐明我的问题的答案,其中所有其他答案都给出了如何上传个性化 MKAnnotation
的回复。他们都有标题字段,但 none 的答案提到标题字段是必要的,结果证明这是主要问题。他们只提到我应该设置 dragState 来控制图钉的移动,但结果证明在我的情况下这是不正确的,如下所示) 无论如何!
下面是我尝试实现 mapView 并添加注释的代码。
var currentLat:CLLocationDegrees!
var currentLong:CLLocationDegrees!
var currentCoordinate:CLLocationCoordinate2D!
....
override func viewDidAppear(animated: Bool) {
let annotation = PinAnnotationClass()
annotation.setCoordinate(currentCoordinate)
//annotation.setCoordinate(currentCoordinate)
//AnnotationView()
self.mapView.addAnnotation(annotation)
}
override func viewDidLoad() {
super.viewDidLoad()
println("hello!")
self.mapView.delegate = self
loadMap()
findPath()
}
func loadMap()
{
currentCoordinate = CLLocationCoordinate2DMake(currentLat, currentLong)
var mapSpan = MKCoordinateSpanMake(0.01, 0.01)
var mapRegion = MKCoordinateRegionMake(currentCoordinate, mapSpan)
self.mapView.setRegion(mapRegion, animated: true)
}
连同扩展名:
extension DetailsViewController: MKMapViewDelegate {
func mapView(mapView: MKMapView!,
viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! {
if annotation is MKUserLocation {
//return nil so map view draws "blue dot" for standard user location
return nil
}
let reuseId = "pin"
var pinView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId) as? MKPinAnnotationView
if pinView == nil {
pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
pinView!.canShowCallout = true
pinView!.draggable = true
pinView!.annotation.coordinate
pinView!.animatesDrop = true
pinView!.pinColor = .Green
}
else {
pinView!.annotation = annotation
}
return pinView
}
func mapView(mapView: MKMapView!, annotationView view: MKAnnotationView!, didChangeDragState newState: MKAnnotationViewDragState, fromOldState oldState: MKAnnotationViewDragState) {
if (newState == MKAnnotationViewDragState.Starting) {
view.dragState = MKAnnotationViewDragState.Dragging
} else if (newState == MKAnnotationViewDragState.Ending || newState == MKAnnotationViewDragState.Canceling){
view.dragState = MKAnnotationViewDragState.None
}
}
func mapView(mapView: MKMapView!, annotationView view: MKAnnotationView!, calloutAccessoryControlTapped control: UIControl!) {
if let annotation = view.annotation as? PinAnnotationClass{
}
}
我还有一个自定义 PinAnnotation class:
import Foundation
import MapKit
class PinAnnotationClass : NSObject, MKAnnotation {
private var coord: CLLocationCoordinate2D = CLLocationCoordinate2D(latitude: 0, longitude: 0)
var coordinate: CLLocationCoordinate2D {
get {
return coord
}
}
var title: String = ""
var subtitle: String = ""
func setCoordinate(newCoordinate: CLLocationCoordinate2D) {
self.coord = newCoordinate
}
最初的问题是注释的 title
没有设置。
如果未设置注释的 title
,则无法将其设置为 "selected" 状态,并且不会显示标注并且 didSelectAnnotationView
不会被调用。
因为要拖动注释,必须先select,没有title
就不能拖动设置。
因此,在创建注释时,将其 title
设置为:
let annotation = PinAnnotationClass()
annotation.title = "hello"
annotation.setCoordinate(currentCoordinate)
这至少应该让你开始拖动它,但由于你使用的是 MKPinAnnotationView
而不是普通的 MKAnnotationView
,你做 not 需要实施 didChangeDragState
。事实上,如果你在使用 MKPinAnnotationView
时实现它,注释将无法正确拖动。
在 didChangeDragState
中,删除设置 view.dragState
的代码——使用 MKPinAnnotationView
时不需要它。
相反,您可以只记录放置注释的坐标:
func mapView(mapView: MKMapView!, annotationView view: MKAnnotationView!, didChangeDragState newState: MKAnnotationViewDragState, fromOldState oldState: MKAnnotationViewDragState) {
if newState == MKAnnotationViewDragState.Ending {
let ann = view.annotation
print("annotation dropped at: \(ann!.coordinate.latitude),\(ann!.coordinate.longitude)")
}
}
不相关,但是
PinAnnotationClass
实现比它需要的更复杂。您不需要为 coordinate
编写显式的获取和设置方法。只需声明 coordinate
,getter/setter 将为您完成:
class PinAnnotationClass : NSObject, MKAnnotation {
var title: String = ""
var subtitle: String = ""
var coordinate: CLLocationCoordinate2D = kCLLocationCoordinate2DInvalid
//kCLLocationCoordinate2DInvalid is a pre-defined constant
//better than using "0,0" which are technically valid
}
您还需要更改坐标的分配方式:
//annotation.setCoordinate(currentCoordinate) //old
annotation.coordinate = currentCoordinate //new
最后,也无关,但是
viewForAnnotation
中的这一行
pinView!.annotation.coordinate
表示什么都不做,去掉。