iOS Mapkit注释不可拖动

4

我是一名新手iOS开发者,需要在iOS地图中实现一个可拖动的注释。我的代码如下所示。无论我做什么,都无法得到一个可拖动的注释。有人能帮忙解决吗?之后,我需要获取指针位置的地址。

RegistrationViewController.swift

class RegistrationViewController: UIViewController,UIPickerViewDelegate,UIPickerViewDataSource,MKMapViewDelegate{
    @IBOutlet weak var mapView: MKMapView!

    override func viewDidLoad() {
        super.viewDidLoad()
        var centerLocation = CLLocationCoordinate2DMake(12.964370125970357, 77.59643554937497)
        var mapspan = MKCoordinateSpanMake(0.01, 0.01)
        var mapregion = MKCoordinateRegionMake(centerLocation, mapspan)
        self.mapView.setRegion(mapregion, animated: true)

        let pin = pinAnnotation(title:"hello",subtitle:"how are you",coordinate:centerLocation)
        mapView.addAnnotation(pin)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    func mapView(mapView: MKMapView!, viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! {
        if annotation is MKPointAnnotation {
            let pinAnnotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "myPin")
            pinAnnotationView.pinColor = .purple
            pinAnnotationView.isDraggable = true
            pinAnnotationView.canShowCallout = true
            pinAnnotationView.animatesDrop = true

            return pinAnnotationView
        }

        return nil
    }

    func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, didChange newState: MKAnnotationViewDragState, fromOldState oldState: MKAnnotationViewDragState) {
        switch newState {
        case .starting:
            view.dragState = .dragging
        case .ending, .canceling:
            view.dragState = .none
        default: break
        }
    }

pinAnnotation.swift

import MapKit

class pinAnnotation:NSObject,MKAnnotation {
    var title:String?
    var subtitle: String?
    var coordinate: CLLocationCoordinate2D
    init(title:String,subtitle:String,coordinate:CLLocationCoordinate2D) {
        self.title = title
        self.subtitle = subtitle
        self.coordinate = coordinate
    }
}
2个回答

5

在您的情况下,annotation 不是 MKPointAnnotation 类型。这就是为什么它没有进入 if annotation is MKPointAnnotation { 条件的原因。

应该像这样:

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {

    if annotation is pinAnnotation {

        let pinAnnotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "myPin")
        pinAnnotationView.pinTintColor = .purple
        pinAnnotationView.isDraggable = true
        pinAnnotationView.canShowCallout = true
        pinAnnotationView.animatesDrop = true

        return pinAnnotationView
    }

    return nil
}

由于annotationpinAnnotation类型。

我在你的代码中没有看到mapView.delegate = self。但是如果你通过Storyboard进行了赋值,那么这是可以的,否则请在viewDidLoad方法中添加它。

完整的代码如下:

import UIKit
import MapKit

class ViewController: UIViewController,MKMapViewDelegate{
    @IBOutlet weak var mapView: MKMapView!


    override func viewDidLoad() {
        super.viewDidLoad()
        mapView.delegate  = self
        let centerLocation = CLLocationCoordinate2D(latitude: 12.964370125970357, longitude: 77.59643554937497)
        let mapspan = MKCoordinateSpanMake(0.01, 0.01)
        let mapregion = MKCoordinateRegionMake(centerLocation, mapspan)
        self.mapView.setRegion(mapregion, animated: true)

        let pin = pinAnnotation(title:"hello",subtitle:"how are you",coordinate:centerLocation)
        mapView.addAnnotation(pin)

    }


    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {

        if annotation is pinAnnotation {

            let pinAnnotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "myPin")
            pinAnnotationView.pinTintColor = .purple
            pinAnnotationView.isDraggable = true
            pinAnnotationView.canShowCallout = true
            pinAnnotationView.animatesDrop = true

            return pinAnnotationView
        }

        return nil
    }

    func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, didChange newState: MKAnnotationViewDragState, fromOldState oldState: MKAnnotationViewDragState) {
        switch newState {
        case .starting:
            view.dragState = .dragging
        case .ending, .canceling:
            view.dragState = .none
        default: break
        }
    }
}

编辑

您可以使用view.annotation?.coordinate获取新位置。

请查看下面的代码:

func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, didChange newState: MKAnnotationViewDragState, fromOldState oldState: MKAnnotationViewDragState) {
    switch newState {
    case .starting:
        view.dragState = .dragging
    case .ending, .canceling:
        //New cordinates
        print(view.annotation?.coordinate)
        view.dragState = .none
    default: break
    }
}

兄弟,你能告诉我如何获取标记指向的位置地址吗? - SHINTO JOSEPH
很高兴能为您提供帮助.. :) - Dharmesh Kheni
谢谢兄弟,你让我一天都很开心。 - SHINTO JOSEPH
更新 view.dragState = .dragging 在我的情况下有助于更新自定义标记位置,谢谢! - Dhaval H. Nena

2
您已经通过将isDraggable属性设置为true完成了第一步。现在您只需要处理用户停止拖动并放置注释的情况,详见:如何在iOS上管理MKAnnotationView的拖放
此外,您的pinAnnotation应该有可设置的坐标。
来自苹果文档

将您的注释视图标记为可拖动的注释视图提供了内置的拖动支持,这使得在地图上拖动注释非常容易,并确保相应地更新注释数据。要实现最小的拖动支持:

在您的注释对象中,实现setCoordinate:方法以允许地图视图更新注释的坐标点。创建注释视图时,将其draggable属性设置为YES。当用户触摸并持有可拖动的注释视图时,地图视图会为其开始拖动操作。随着拖动操作的进行,地图视图调用其委托的mapView:annotationView:didChangeDragState:fromOldState:方法来通知它对视图的拖动状态进行更改。您可以使用此方法来影响或响应拖动操作。

要在拖动操作期间动画显示您的视图,请在注释视图中实现自定义dragState方法。当地图视图处理与拖动相关的触摸事件时,它会更新受影响的注释视图的dragState属性。实现自定义dragState方法使您有机会拦截这些更改并执行其他操作,例如动画显示您的视图。例如,MKPinAnnotationView类在拖动操作开始时将图钉从地图上抬起,并在结束时将图钉放回地图上。

您缺少mapView:annotationView:didChangeDragState:fromOldState:方法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接