2017-01-16 103 views
0

我的這個應用程序的目的是允許用戶在一個選項卡控制器的一個選項卡中輸入任何一組座標,而在另一個選項卡中,座標將被放置在一個引腳帶註釋。Swift將座標添加到數組並添加到地圖

我一直在試圖實現的方法是使用全局數組,附加輸入座標並在其他類文件(使用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(註釋)」 它說,一個無發現當試圖解開一個可選。所以我認爲錯誤在於信息沒有保存在註釋中,但我不能立即看到這是錯誤的。

此方法的任何替代方法都可以更容易實現,歡迎您!

回答

1

1)您實際上正在創建一個新的MapViewController,本地範圍在addToMap方法內。這個新的視圖控制器是以編程方式創建的,並且與UITabBarViewControllerMapViewController實例無關。它的mapView插座設置爲nil,因此當您嘗試訪問該屬性時,隱式解包將會找到nil,導致您的應用程序崩潰。此外,視圖控制器本地實例將在addToMap方法的末尾釋放。

2)所以,你想要做的是通過UITabBarController訪問已存在的MapViewController。但是,如果在用戶至少切換到地圖視圖選項卡之前嘗試訪問插座,則會看到相同的崩潰。這是因爲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) 
} 
+0

啊我現在看到「let mapVC:MapViewController = MapViewController()」並沒有引用由UITabBarViewController控制的實際MapViewController。另外,感謝您指出每次函數迭代時,它都會重複相同的註釋。但是,在使用您的建議之後,MapView上沒有註釋。 (但該應用程序不會崩潰!)你知道可能是什麼問題? – Kevin

+1

我建議嘗試以下方法:1)在將地圖添加到地圖後,將地圖居中放置到註釋的座標上,即''''self.mapView.centerCoordinate = annotation.coordinate'''' 'add'''方法。 2)嘗試一個iOS 9模擬器。 3)添加註釋後,嘗試在調試器中打印mapView.annotations屬性。 4)嘗試UI調試器來查看註釋是否超出範圍。讓我知道是否有任何上述幫助! – stakri

+0

事實證明,西方座標需要輸入爲負座標! self.mapView.centerCoordinate = annotation.coordinate幫我弄明白了! – Kevin