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

4
我正在尝试构建一个地图应用程序,可以接收用户输入的纬度和经度坐标,并在输入后,在不同的选项卡上放置一个"pin"。我的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个回答

2
我认为你需要做的是从tabBarController中获取你的第二个ViewController MapViewController,然后将坐标数组传递给它,在addToMap Action中使用以下代码替换原来的代码。
@IBAction func addToMap(_ sender: Any) {
        let lat = Double(latitudeField.text!)
        let long = Double(longitudeField.text!)

        self.coordinates.append(CLLocationCoordinate2D(latitude: lat!, longitude: long!))
        //here we pass the coordinate array to mapViewController
        if let mapViewController = self.tabBarController?.viewControllers?[1] as? MapViewController
        {
            mapViewController.coordinates = self.coordinates
        }
    }

你还需要添加一个导航控制器,就像图片中的一样。 enter image description here 希望这能帮到你。

你能发布一下你的错误吗?请记住,CLLocation2D不是任何浮点数,您必须检查它是否有效。如果您愿意,我可以改进我的回答。 - Reinier Melian
我遇到了“Thread 1: EXC_BAD_INSTRUCTION”错误。这可能与ClLocation2D中的数字类型有关吗? - Kevin
抱歉,我不熟悉什么是estacktrace。那是整个控制台错误吗? - Kevin
是的,你可以发布它吗? - Reinier Melian
我的错误是:"fatal error: unexpectedly found nil while unwrapping an Optional value (lldb)",当我输入坐标时出现的。我该如何检查CLLocation2D是否有效? - Kevin
显示剩余3条评论

1

一般来说,如果存在父子关系并且可以在prepareForSegue或反向传值(unwind)中完成,则我只使用直接从一个ViewController传递数据到下一个的方法。否则,我认为最好使用通知的发布者-订阅者模型。当您的坐标更改时,您可以发布一个通知:

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 不需要关心谁需要更新;订阅者负责自行注册。

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