Swift 将坐标附加到数组并添加到地图

Swift Appending Coordinates into Array and Adding to Map

我的这个应用程序的目的是允许用户在选项卡控制器的一个选项卡中输入任何一组坐标,而在另一个选项卡中,坐标将被放置在带有注释的图钉中。

我一直在尝试实现的方法是使用一个全局数组,它附加输入坐标并在另一个 class 文件(使用 mapView)中调用。我在尝试遍历数组以放置引脚时遇到了很多问题,我不确定哪里出了问题。

输入信息class文件:

import UIKit
import CoreLocation

var locations: [Dictionary<String, Any>] = [] // here I initialize my array

class OtherVC: UIViewController {

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

    @IBOutlet weak var titleTextField: UITextField!
    var coordinates = [CLLocationCoordinate2D]()

    override func viewDidLoad() {
        super.viewDidLoad()
    }



 // This IBOutlet takes the coordinate input information from the user
 @IBAction func addToMap(_ sender: Any) {
    let lat = latitudeField.text!
    let long = longitudeField.text!
    let title = titleTextField.text!
    var location: [String: Any] = ["title": title, "latitude": lat, "longitude": long]
    locations.append(location) // adding the info to the array
    let mapVC : MapViewController = MapViewController()
    mapVC.iterateLocations()

    }


}

MapView class 文件:

import UIKit
import MapKit
class MapViewController: UIViewController, MKMapViewDelegate {


    @IBOutlet weak var mapView: MKMapView!



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

    // this method here iterates through each of the locations in the array
    func iterateLocations() -> Bool {
        for location in locations {

            var momentaryLat = (location["latitude"] as! NSString).doubleValue
            var momentaryLong = (location["longitude"] as! NSString).doubleValue
            let annotation = MKPointAnnotation()
            annotation.title = location["title"] as? String
            annotation.coordinate = CLLocationCoordinate2D(latitude: momentaryLat as CLLocationDegrees, longitude: momentaryLong as CLLocationDegrees)
            mapView.addAnnotation(annotation)
        }
        return true
    }


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

第 "mapView.addAnnotation(annotation)" 行中弹出错误,提示在尝试解包 Optional 时发现 nil。所以我认为错误是信息没有保存在注释中,但我没有立即看出哪里错了。

欢迎使用可能更容易实施的此方法的任何替代方法!

1) 您实际上是在 addToMap 方法内创建一个具有局部作用域的新 MapViewController。这个新的视图控制器是以编程方式创建的,与 UITabBarViewControllerMapViewController 实例无关。它的 mapView 出口设置为 nil,因此当您尝试访问该 属性 时,隐式解包将找到 nil,导致您的应用程序崩溃。此外,视图控制器本地实例将在 addToMap 方法结束时被释放。

2) 因此,您要做的是通过 UITabBarController 获取对已经存在的 MapViewController 的访问权限。但是同样,如果您在用户切换到地图视图选项卡至少一次之前尝试访问 mapView 出口,您将看到同样的崩溃。这是因为 MapViewController 的视图不会被加载(视图仅在需要时从 nib 加载,即在这种情况下,当用户点击地图视图选项卡并且它变得可见时)。您可以强制加载视图,并通过调用 loadViewIfNeeded().

设置 mapView 插座

3) 每次调用 addToMap 时,您都将新位置附加到之前的位置,然后遍历所有位置以创建注释。这会导致相同的注释被多次添加到地图中。您可以将 iterateLocations 方法更改为 add(newLocation:[String:Any]) 之类的方法,并只传递从用户输入中获得的最后一个位置。

所以一种解决方案是替换:

let mapVC : MapViewController = MapViewController() 里面 addToMap 有:

let mapVC : MapViewController = self.tabBarController!.viewControllers![1] as! MapViewController
mapVC.loadViewIfNeeded()
mapVC.add(newLocation:location)

假设 OtherVC 位于标签视图控制器的索引 0,MapViewController 位于索引 1。还有:

func add(newLocation location:[String:Any]) {
        let momentaryLat = (location["latitude"] as! NSString).doubleValue
        let momentaryLong = (location["longitude"] as! NSString).doubleValue
        let annotation = MKPointAnnotation()
        annotation.title = location["title"] as? String
        annotation.coordinate = CLLocationCoordinate2D(latitude: momentaryLat as CLLocationDegrees, longitude: momentaryLong as CLLocationDegrees)
        mapView.addAnnotation(annotation)
}