2017-04-05 3 views
0

Ich habe eine Async-Funktion (geocodeAddressString), die in der Funktion prepreve for segue aufgerufen wird. Das Problem ist, dass diese asynchrone Funktion nach der Ausführung des Segments zurückkehrt. Die folgende Async-Funktion konvertiert eine Adresszeichenfolge in Koordinaten. Ich kann diese asynchrone Funktion vor dieser Vorbereitungsfunktion nicht aufrufen, da das Benutzeradressfeld jederzeit vom Benutzer bearbeitet werden kann. Ich habe versucht, die Async-Funktion aufzurufen, wenn die Save-Taste gedrückt wird, und dann den Abschnitt zu codieren, wenn die Async-Funktion zurückkehrt, aber dann ist die Ladezeit zwischen der gedrückten Taste und dem auftretenden Übergang zu lang.Schnelle asynchrone Abfangfunktion in anderer Ansicht

Also meine Frage ist, ob es irgendwie möglich ist, dass ich diese asynchrone Methode in der neuen Ansicht abfangen kann? Dann könnte ich einfach einige temporäre Koordinaten durch die tatsächlich zurückgegebenen Werte ersetzen. Jede Hilfe wird geschätzt, Danke!

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {  
    //convert address to coordinates 
    let geoCoder = CLGeocoder() 
    geoCoder.geocodeAddressString(addressTxt.text!) { (placemarks, error) in 
     guard 
      let placemarks = placemarks, 
      let location = placemarks.first?.location 
      else { 
       // handle no location found 
       return 
     } 

      let tempCoord = CLLocationCoordinate2D(latitude: (location.coordinate.latitude), longitude: (location.coordinate.longitude)) 
      self.donatedItem = DonatedItem(self.titleTxt.text!, self.itemImg.image!, self.donated, self.descTxt.text!, expirationDate, tempCoord, (user?.uid)!, (self.donatedItem?.itemID)!, self.addressTxt.text!, reserved: false, reservedBy: "NA") 
      self.donatedItem?.updateItem() 
    } 

    switch(segue.identifier ?? "") { 
    case "saveItem": 

     homeViewController.isReturningSegue = true 
     homeViewController.tempItem = self.donatedItem 

    default: 
     print("Undefined segue") 
    } 
} 

Antwort

1

Natürlich können Sie. Veröffentlichen Sie eine Benachrichtigung, um die neue Ansicht zu benachrichtigen. Oder benutze den Verschluss. Dies ist beispielsweise eine Benachrichtigung.

NotificationCenter.default.post(name: Notification.Name(rawValue: "locationUpdated"), object: coordinate) 

So wird das mit dem Schließen gemacht.

typealias closure = (String) -> Void 

class A: UIViewController { 
    var coordinateUpdated: closure? // call this after coordinate updated 

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 
     if let b = segue.destination as? B { 
      coordinateUpdated = b.coordinateUpdated 
     } 
    } 
} 

class B: UIViewController { 
    let coordinateUpdated: closure = { (coordinate: String) in 
     // update here 
    } 


} 
0

könnten Sie auf addressTxt.text! passieren statt und rufen dann die Asynchron-Methode in den nächsten View-Controller.

Im aktuellen View-Controller:

homeViewController.isReturningSegue = true 
homeViewController.tempItem = self.donatedItem 
homeViewController.address = self.addressTxt.text! 

Im nächsten View-Controller:

func viewWillAppear() { 
    supper.viewWillAppear() 
    let geoCoder = CLGeocoder() 
    geoCoder.geocodeAddressString(self.address) { ... } 
} 

Wenn geocodeAddressString dauert zu lange (und beeinflussen die UX) Sie setzen könnte up eine Fortschrittsanzeige. Zum Beispiel ist MBProgressHUD ein ziemlich allgemeines Framework für solche Aufgaben.

+0

Danke für den Tipp. Ich ziehe es vor, Fortschrittsindikatoren zu vermeiden, wenn ich kann, aber ich werde diesen Rahmen für Situationen berücksichtigen, in denen das Laden unvermeidbar ist. –

Verwandte Themen