2016-12-23 2 views
4

Ich versuche eine Karten-App zu erstellen, die Benutzereingaben von Längen- und Breitenkoordinaten erhalten kann, wenn Pin auf einer Karte in einer anderen Registerkarte platziert wird. Mein FirstVC besteht aus einer Schaltfläche "Orte hinzufügen", die zu OtherVC führt, in die der Benutzer die Koordinaten eingeben kann. SecondVC besteht aus dem MapView. Meine anfängliche Idee ist, ein spezifisches Koordinatenfeld zu haben, und alle neuen Koordinaten werden an dieses Feld angehängt. Die Ausführung fehlt mir, weil ich nicht sicher bin, wie ich dieses Array auf MapView übertragen soll. Hier ist, was ich bisher:Swift MKMapViewDelegate - Übertragen von Koordinaten zwischen den View-Controllern

Für die Eingabe von Koordinaten:

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




} 

Für die MapView:

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

enter image description here

Antwort

2

Ich glaube, Sie brauchen, ist Ihre zweite Viewcontroller erhalten MapViewController von Ihrem TabBarController und übergeben Sie dann die Koordinaten-Array, so in Ihrer AddToMap Aktion ersetzen Sie diese mit

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

Sie müssen auch eine Navigation-Controller hinzuzufügen, wie im Bild enter image description here

Ich hoffe, das hilft Ihnen

+0

Ich habe eine Break-Anweisung in die if-let-Anweisung eingefügt, und es sieht so aus, als ob die Koordinaten ausgeführt und übertragen werden. Allerdings bekomme ich einen Fehler mit "mapView.addAnnotation (Annotation)", wenn ich die Koordinaten in mapViewController erhalte. Nicht ganz sicher, was das Problem ist. – Kevin

+0

Können Sie Ihren Fehler ?, Denken Sie daran, dass CLLocation2D keine Float-Nummer ist, müssen Sie überprüfen, ob gültig ist, kann ich meine Antwort verbessern, wenn Sie –

+0

Ich bekomme den Fehler "Thread 1: EXC_BAD_INSTRUCTION" .. Könnte dies verwandt sein die Art der Nummer in ClLocation2D? – Kevin

1

Generell habe ich nur die Methode der direkt verwenden, um die Daten von einem Viewcontroller auf die Weitergabe Als nächstes, wenn es eine Eltern-Kind-Beziehung gibt, und ich kann es in prepareForSegue oder in und abwickeln (Kind zum Elternteil). Ansonsten finde ich es besser, das Publisher-Subscriber-Modell mit Notification zu verwenden. Wenn Sie Ihre Änderungen koordinieren schreiben Sie eine Benachrichtigung:

NotificationCenter.default.post(name: NSNotification.Name("MapViewController.coordinate.updated"), object: self, userInfo: nil) 

Jetzt kann jeder, der über MapViewController Koordinaten kümmert sich kann zu ändern hören:

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

Dies macht die Ansichten lose gekoppelt und MapViewController braucht sich nicht um die Pflege muss aktualisiert werden; Die Abonnenten sind für die Registrierung selbst verantwortlich.

Verwandte Themen