【问题标题】:Swift Appending Coordinates into Array and Adding to MapSwift 将坐标添加到数组并添加到地图
【发布时间】:2017-01-17 04:23:22
【问题描述】:

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

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

输入信息类文件:

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 类文件:

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。所以我认为错误是信息没有保存在注释中,但我没有立即看到这是错误的。

欢迎任何可能更容易实现的方法的替代方法!

【问题讨论】:

    标签: arrays swift mkmapview coordinates


    【解决方案1】:

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

    2) 所以,您要做的是通过UITabBarController 获得对已经存在的MapViewController 的访问权限。但同样,如果您在用户至少切换到地图视图选项卡之前尝试访问mapView 插座,您将看到同样的崩溃。这是因为MapViewController 的视图将不会被加载(视图仅在需要时从笔尖加载,即在这种情况下,当用户点击地图视图选项卡并变为可见时)。您可以通过调用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)
    }
    

    【讨论】:

    • 啊,我现在看到“let mapVC : MapViewController = MapViewController()”并不是指由 UITabBarViewController 控制的实际 MapViewController。另外,感谢您指出每次函数迭代时,它都会重复相同的注释。但是,使用您的建议后,MapView 上没有放置注释。 (但应用程序不再崩溃了!)您知道可能是什么问题吗?
    • 我建议尝试以下方法:1)在将注释添加到地图后立即将地图居中到注释的坐标,即add方法末尾的self.mapView.centerCoordinate = annotation.coordinate。 2) 试用 iOS 9 模拟器。 3) 添加注释后,尝试在调试器中打印 mapView.annotations 属性。 4) 试用 UI 调试器,查看注解是否越界。如果上述任何方法有帮助,请告诉我!
    • 原来西坐标需要输入负坐标! self.mapView.centerCoordinate = annotation.coordinate 帮我弄清楚了!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-07-25
    • 2017-07-17
    • 1970-01-01
    • 2018-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多