ios - MKAnnotation Pin 不会拖动,即使设置为可拖动

标签 ios swift mkmapview mkpinannotationview mkmapviewdelegate

多年来,我一直在尝试在 map View 上添加可拖动的注释。 (我使用的是默认图钉,不是我自己的)到目前为止,我只能在设定的坐标上显示它(真的不是什么成就),我需要首先获得注释才能对被选中使用react,它不会永远不会被 didChangeDragState 函数接收到。然后我需要能够拖动它,将它放在新位置并获取新位置的坐标。

我是 Swift 的新手,但我接手了一个相当困难的项目。 我已经查看了我在 google 上找到的几乎所有内容,以寻找“Swift 中可拖动的 MKAnnotation mapkit”和类似的变体。(编辑:我没有找到任何可以阐明的答案我的问题,所有其他答案都对如何上传个性化MKAnnotation做出了回应。他们都有标题字段,但没有一个答案提到标题字段是必要的,结果证明这是主要的问题。他们只提到我应该设置 dragState 来控制 pin 的移动,但结果证明在我的情况下这是不正确的,如下所示) 无论如何! 下面是我尝试实现 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 类:

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,则无法将其设置为“已选择”状态,并且不会显示标注,并且不会调用 didSelectAnnotationView

由于要拖动注释,必须先选中,如果没有设置title,则无法拖动。

因此在创建注释时,将其 title 设置为:

let annotation = PinAnnotationClass()
annotation.title = "hello"
annotation.setCoordinate(currentCoordinate)


这至少应该让您开始拖动它,但是由于您使用的是 MKPinAnnotationView 而不是普通的 MKAnnotationView,您/em> 需要实现 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 编写明确的 get 和 set 方法。只需声明 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

意味着什么都不做,删除它。

关于ios - MKAnnotation Pin 不会拖动,即使设置为可拖动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30021305/

相关文章:

ios - canShowCallout 按钮不起作用

ios - Pass label text from one view controller to another using segues only if button (checkbox) is selected

ios - 在 iOS 中加载 3D 模型

ios - UIKeyboardTaskQueue 只能从主线程调用

ios - UNNotificationServiceExtension didReceive 未调用

ios - 为注释添加标题

iphone - 更新 MKMapView 上自定义注释的标题/副标题

javascript - 禁用 iPad Safari 浏览器中的 'Copy' 功能

ios - 从 webview 链接快速启动位智

ios - 在 iOS 图表的左轴上显示文本