Swift MKMapViewDelegate-在视图控制器之间传输坐标
我正在尝试构建一个地图应用程序,它可以接收用户输入的纬度和经度坐标,当输入时,将在地图上的不同选项卡中放置一个pin。我的第一个VC包含一个“添加位置”按钮,该按钮连接到其他VC,用户可以输入坐标。SecondVC由MapView组成。我最初的想法是有一个特定的坐标数组,任何新的坐标都会附加到这个数组中。我缺少执行,因为我不确定如何将此数组传输到MapView。以下是我到目前为止的情况: 对于坐标的输入:Swift MKMapViewDelegate-在视图控制器之间传输坐标,swift,mkmapview,mkmapviewdelegate,Swift,Mkmapview,Mkmapviewdelegate,我正在尝试构建一个地图应用程序,它可以接收用户输入的纬度和经度坐标,当输入时,将在地图上的不同选项卡中放置一个pin。我的第一个VC包含一个“添加位置”按钮,该按钮连接到其他VC,用户可以输入坐标。SecondVC由MapView组成。我最初的想法是有一个特定的坐标数组,任何新的坐标都会附加到这个数组中。我缺少执行,因为我不确定如何将此数组传输到MapView。以下是我到目前为止的情况: 对于坐标的输入: import UIKit import CoreLocation class Other
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!))
}
}
对于地图视图:
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
}
}
我认为您需要的是从tabBarController中获取第二个ViewController
MapViewController
,然后传递坐标数组,因此在addToMap操作中,将其替换为
@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
}
}
您还需要添加导航控制器,如图所示
我希望这对您有所帮助一般来说,如果存在父子关系,我只会使用直接将数据从一个ViewController传递到下一个ViewController的方法,并且我可以在prepareForSegue或in and unwind(子到父)中执行此操作。否则,我认为最好使用带有通知的publisher-subscriber模型。当坐标发生变化时,您会发布通知:
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不需要关心谁需要更新;订阅者负责自己注册。我在if-let语句中添加了一个break语句,看起来它运行并传输坐标。但是,在接收mapViewController中的坐标时,“mapView.addAnnotation(annotation)”出现错误。不太清楚问题是什么。你能发布你的错误吗?记住CLLocation2D不是任何浮点数,你必须检查它是否有效,如果你想知道我得到的错误是“线程1:EXC\U BAD\U指令”,我可以改进我的答案。。这可能与ClLocation2D中的数字类型有关吗?这可能与文本字段中缺少验证有关,也可能与CLLLocation2D的验证有关,请发布您的崩溃estacktraceSorry,我不熟悉estacktrace是什么。这就是整个控制台的错误吗?