2014-09-13 53 views
2

我试图给用户输入地址并让地图缩放到其中的能力。当使用MapKit时,可以在Swift中使用可拖动的注释

我想让用户将别针拖到另一个位置,然后获取位置信息并将其用于任何内容。

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

我的自定义注解视图:

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


} 

我的控制器,里面我的MapView:

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示例。

回答

3

可设置的coordinate属性属于实现MKAnnotation协议的对象。

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


MKAnnotationView类(和你的CustomAnnotationView子类)都没有实现MKAnnotation的对象。它们是注释模型对象的可视化表示。


这里的Location and Maps Programming Guide说什么:

为了实现最小支持拖拽:

  • 在你的注释对象,实施setCoordinate:方法 允许地图视图更新注释的坐标点。
  • 创建注释视图时,请将其draggable属性设置为YES。

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


didTapGoButton,代码添加MKPlacemark类型的不实施setCoordinate:的注解。

相反,你需要使用内置MKPointAnnotation实现setCoordinate:或创建一个实现MKAnnotation协议(MKAnnotationView一个子类)自己的自定义类,并提供了一个可设置coordinate属性。

因此,不是这样的:

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类,如果你喜欢,但它没有必要只是为了创建一个自定义图像注释视图它绝对不需要坐标属性。

+0

摆脱了CustomAnnotationView。一切正常,但有一件事已经改变。当我点击引脚时,它通常显示我输入的邮政编码区域的名称。但现在它显示我输入到文本区域的内容。无论如何显示关于引脚被绘制的详细信息? – LondonGuy 2014-09-14 04:33:29

+0

好吧搞乱pa.title = placemark.locality等帮助。我想我可以连接一些字符串。我会看看我的选择。谢谢您的帮助 – LondonGuy 2014-09-14 04:40:59

0

如果您需要/喜欢使用MKPlacemark,您将无法覆盖坐标属性,因此既不实现setCoordinate:method for real,也就是平均更改MKPlacemark坐标。在这种情况下最好的事情是将MKPointAnnotation继承并添加一个MKPlacemark类型的私有属性。欲了解更多详情,请关注我的帖子How to have draggable annotations in Swift when using MKPlacemark

相关问题