ios - 使用MapKit时,Swift中是否可以有可拖动的注释

标签 ios cocoa-touch swift mkmapview mkannotationview

我试图让用户能够输入地址并让 map 缩放到该地址,这是可行的。

我想允许用户将图钉拖到另一个位置,然后获取该位置的信息并将其用于任何用途。

我已经尝试过了,但我最多能做的就是将实际的引脚更改为自定义图像。我已经阅读了几篇文章和教程(全部针对 Objective-c),即使在转换代码之后我仍然无法让它工作。

我的自定义注释 View :

import Foundation
import MapKit
class CustomAnnotationView: MKAnnotationView {

    var coordinate:CLLocationCoordinate2D!

    init(coordinate:CLLocationCoordinate2D) {
        super.init()
        self.coordinate = coordinate
    }

    override init(frame: CGRect) {
        super.init(frame: CGRect())
    }

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override init(annotation: MKAnnotation!, reuseIdentifier: String!) {
        super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
        image = UIImage(named: "pin")
        draggable = true
        canShowCallout = true
    }

    func setCoordinate(newCoordinate: CLLocationCoordinate2D){
         self.coordinate = newCoordinate;
    }


}

容纳我的 map View 的 Controller :

import Foundation
import MapKit
class LocationViewController : UIViewController, MKMapViewDelegate {

    @IBOutlet weak var mapView: MKMapView!
    @IBOutlet weak var searchField: UITextField!
    @IBOutlet weak var addressLabel: UILabel!
    @IBOutlet weak var locationInstructions: UITextView!


    @IBAction func didTapGoButton(sender: UIButton) {

        var geocoder = CLGeocoder()
        geocoder.geocodeAddressString(searchField.text, {(placemarks: [AnyObject]!, error: NSError!) -> Void in
            if let placemark = placemarks?[0] as? CLPlacemark {
                var region = self.mapView.region as MKCoordinateRegion
                region.center = placemark.location.coordinate
                region.span.longitudeDelta /= 30.0;
                region.span.latitudeDelta /= 30.0;

                self.mapView.zoomEnabled = true
                self.mapView.scrollEnabled = true
                self.mapView.addAnnotation(MKPlacemark(placemark: placemark))
                self.mapView.setRegion(region, animated: true)
            }

        })
    }

    func mapView(mapView: MKMapView!, viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! {

        if annotation.isKindOfClass(MKUserLocation) {
            return nil
        }

        var pin = mapView.dequeueReusableAnnotationViewWithIdentifier("CustomAnnotationView")

        if pin == nil {
            NSLog("PIN NIL")
            pin = CustomAnnotationView(annotation: annotation, reuseIdentifier: "CustomAnnotationView")

        }
        else
        {
            NSLog("PIN NOT NIL")
            pin.annotation = annotation;
        }

        return pin;
    }

    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;
        }
    }

我错过了什么?

我找不到任何成功完成此操作的 Swift 示例。

最佳答案

可设置的坐标属性属于实现MKAnnotation协议(protocol)的对象。

实现 MKAnnotation 协议(protocol)的对象是您传递给 addAnnotation 的对象。


MKAnnotationView 类(以及您的 CustomAnnotationView 子类)不是实现 MKAnnotation 的对象。它们是注释模型对象的视觉表示。


这就是Location and Maps Programming Guide说:

To implement minimal support for dragging:

  • In your annotation objects, implement the setCoordinate: method to allow the map view to update the annotation’s coordinate point.
  • When creating your annotation view, set its draggable property to YES.

您的“注释对象”与您的“注释 View ”不同。


didTapGoButton 中,代码添加了 MKPlacemark 类型的注释,该注释实现 setCooperative:

相反,您需要使用内置的 MKPointAnnotation 类,该类确实实现 setCooperative: 或创建您自己的自定义类实现 MKAnnotation 协议(protocol)(不是MKAnnotationView的子类)并提供可设置的坐标属性。

所以代替这个:

self.mapView.addAnnotation(MKPlacemark(placemark: placemark))

这样做:

let pa = MKPointAnnotation()
pa.coordinate = placemark.location.coordinate
pa.title = placemark.name //or whatever title you like
self.mapView.addAnnotation(pa)

如果您愿意,您仍然可以保留您的 CustomAnnotationView 类,但没有必要仅仅使用自定义图像创建注释 View ,并且它绝对不需要坐标属性。

关于ios - 使用MapKit时,Swift中是否可以有可拖动的注释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25826221/

相关文章:

iphone - 调用ReloadData时UITableView绘图问题

iphone - CLLocationManager distanceFilter 会做些什么来节省电量吗?

swift - 快速访问navigationController subview 的项目

ios - 在没有 UIScrollView 的情况下使用 UIPageControl

ios - 为什么SwiftUI对@Binding和@State vars要求_propertyName样式初始化?

ios - Objective-C . 如果文本字段等于某物,我希望标签显示特定文本

Php脚本无法在服务器上上传图片

ios - Xcode - 如何修复 'NSUnknownKeyException' ,原因 : … this class is not key value coding-compliant for the key X"error?

ios - 导航弹出 View Controller 时如何更改动画方向

ios - 翠鸟图像在加载前是否已调整大小?