这个应用程序的目的是允许用户在一个选项卡控制器的一个选项卡中输入任意一组坐标,而在另一个选项卡中,坐标将被放置在带有注释的管脚中。
我一直在尝试实现的方法是使用一个全局数组,该数组追加输入坐标并在另一个类文件中调用(使用mappview)。我在尝试遍历数组以放置管脚时遇到了一系列问题,我不确定出了什么问题。
输入信息类文件:
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)”行中会弹出一个错误,表示在尝试展开可选项时找到了nil。所以我认为错误在于信息没有保存在注释中,但是我并没有立即发现这是错误的。
欢迎使用此方法的任何替代方法,这些方法可能更易于实现!
最佳答案
1)您实际上正在创建一个新的MapViewController
,其中本地作用域位于addToMap
方法内。这个新的视图控制器是以编程方式创建的,与MapViewController
的UITabBarViewController
实例无关。它的mapView
出口设置为nil
,因此当您尝试访问该属性时,隐式展开将找到nil
,从而导致您的应用程序崩溃。此外,视图控制器本地实例将在addToMap
方法的末尾被释放。
2)所以,你想做的是通过MapViewController
获取对已经存在的UITabBarController
的访问。但是,如果您在用户至少切换到“地图视图”选项卡一次之前尝试访问mapView
插座,您将看到相同的崩溃。这是因为MapViewController
的视图不会被加载(该视图仅在需要时从nib加载,即在这种情况下,当用户点击map view选项卡时,该视图变为可见)。您可以通过调用mapView
来强制加载视图和设置loadViewIfNeeded()
出口。
3)每次调用addToMap
时,都会将新位置附加到前面的位置,然后遍历所有位置以创建注释。这将导致同一注释多次被添加到映射中。您可以将iterateLocations
方法更改为类似于add(newLocation:[String:Any])
的方法,只需传递从用户输入获得的最后一个位置。
因此,一个解决方案是替换:let mapVC : MapViewController = MapViewController()
内部带有:
let mapVC : MapViewController = self.tabBarController!.viewControllers![1] as! MapViewController
mapVC.loadViewIfNeeded()
mapVC.add(newLocation:location)
假设
addToMap
位于索引0,OtherVC
位于选项卡视图控制器的索引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)
}
关于arrays - 快速将坐标追加到数组中并添加到 map ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41682251/