Swift MKMapViewDelegate - 在视图控制器之间传输坐标

时间:2016-12-23 02:27:42

标签: swift mkmapview mkmapviewdelegate

我正在尝试构建一个地图应用程序,该应用程序可以接收用户输入的纬度和经度坐标,输入时,会在不同选项卡的地图上放置图钉。我的FirstVC包含一个按钮" Add Locations"它会转移到用户可以输入坐标的OtherVC。 SecondVC由MapView组成。我最初的想法是有一个特定的坐标数组,任何新的坐标都将附加到这个数组。执行是我缺乏的地方,因为我不确定如何将此数组传输到MapView。以下是我到目前为止的情况:

对于坐标输入:

import UIKit
import CoreLocation

class OtherVC: UIViewController {

@IBOutlet weak var latitudeField: UITextField!
@IBOutlet weak var longitudeField: UITextField!

var coordinates = [CLLocationCoordinate2D]()

override func viewDidLoad() {
    super.viewDidLoad()

}


@IBAction func addToMap(_ sender: Any) {
    let lat = Double(latitudeField.text!)
    let long = Double(longitudeField.text!)

    self.coordinates.append(CLLocationCoordinate2D(latitude: lat!, longitude: long!))
}




}

对于MapView:

import UIKit
import MapKit
class MapViewController: UIViewController, MKMapViewDelegate {
@IBOutlet weak var mapView: MKMapView!



var coordinates = [CLLocationCoordinate2D]() {
    didSet {
        // Update the pins
        // Since it doesn't check for which coordinates are new, it you go back to
        // the first view controller and add more coordinates, the old coordinates
        // will get a duplicate set of pins
        for (index, coordinate) in self.coordinates.enumerated() {
            let annotation = MKPointAnnotation()
            annotation.coordinate = coordinate
            annotation.title = "Location \(index)"

            mapView.addAnnotation(annotation)
        }
    }
}

override func viewDidLoad() {
    super.viewDidLoad()
    mapView.delegate = self
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
    let identifier = "pinAnnotation"
    var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? MKPinAnnotationView

    if annotationView == nil {
        annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
        annotationView?.canShowCallout = true
    }

    annotationView?.annotation = annotation
    return annotationView
}
}

enter image description here

2 个答案:

答案 0 :(得分:2)

我认为你需要从你的tabBarController获取你的第二个ViewController // childView.translatesAutoresizingMaskIntoConstraints = false addChildViewController(dayExpenseVC) dayExpenseVC.view.frame = childView.frame childView.addSubview(dayExpenseVC.view) dayExpenseVC.didMove(toParentViewController: self) ,然后传递坐标数组,所以在你的addToMap Action中替换为这个

MapViewController

您还需要添加导航控制器,如图所示 enter image description here

我希望这有助于你

答案 1 :(得分:1)

一般来说,如果存在父子关系,我只使用直接将数据从一个ViewController传递到下一个ViewController的方法,我可以在prepareForSegue或in和unwind(child to parent)中执行。否则我认为最好将发布者订阅者模型与通知一起使用。当您的坐标发生变化时,您会发布通知:

NotificationCenter.default.post(name: NSNotification.Name("MapViewController.coordinate.updated"), object: self, userInfo: nil)

现在任何关心MapViewController坐标变化的人都可以听:

override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(self, selector: #selector(coordinateUpdated), name: NSNotification.Name("coordinate.updated"), object: nil)
}

deinit {
    NotificationCenter.default.removeObserver(self)
}

@objc private func coordinateUpdated( notification: Notification) {
    if let source = notification.object as? MapViewController {
        print(source.coordinates)
    }
}

这使得视图松散耦合,MapViewController不需要关心谁需要更新;订阅者负责注册自己。