2016-01-22 4 views
6

Ich habe eine Reihe von View-Controllern (eingebetteter Navigationscontroller), und ich muss einige Async-Aufrufe durchführen, bevor ich zum nächsten Bildschirm übergehe. Das Problem ist, dass ich diesen Aufruf zu der Zeit machen muss, wenn ich auf die Schaltfläche klicke, die dem Segment zugeordnet ist, aber da der Async-Aufruf noch nicht zurückgegeben wurde, wird der Übergang gemacht und der nächste Ansichtscontroller angezeigt. Wie machen Menschen so etwas, um zu verhindern, dass die Navigation in der Ansichts-Steuerung stattfindet, bevor der asynchrone Aufruf zurückgegeben wird?Einen asynchronen Anruf vor einem Übergang zum nächsten View-Controller machen (Swift)

+1

Haben Sie einen Code zu zeigen? – iamalizade

+1

Tun Sie es nicht, stattdessen tun Sie es in der neuen Steuerung – Wain

+0

Ich kann es nicht in der nächsten Controller tun, da der nächste View-Controller sollte nur angezeigt werden, wenn die Async-Methode erfolgreich ist. – u84six

Antwort

5

TL; DR Sie kann eine @IBAction für die UIButton erstellen und innerhalb der Funktion den Async-Aufruf vornehmen und den Abschnitt manuell im completionHandler mit der dispatch_async(dispatch_get_main_queue()) {} starten.

enter image description here

Und dann werden Sie sehen, welche Art von Segue wählen:

Um Ihre segue manuell nur Ctrl + Drag vom UIViewController zum nächsten wie im folgenden Bild zu erstellen wie in diesem Bild:

enter image description here

Nachdem Sie den Show Typ wählen Sie die segue in der Hierarchie der Ansicht in der linken wählen sie die Kennung der Segue wie in diesem Bild setzen sehen:

enter image description here Sie Ihr Problem der segue starten umgehen kann manuell mit Mit der Funktion performSegueWithIdentifier können Sie im Web referenzieren, um viele Anleitungen zum manuellen Erstellen eines Segments mit dem Interface Builder zu erhalten.

Sobald Sie wurde erstellt segue können Sie es überall rufen Sie wollen, in Ihrem Fall, wie Sie es in einem completionHandler eines Asynchron-Aufruf rufen Sie im Hauptthread einfügen müssen, mit der dispatch_async(dispatch_get_main_queue()) {} Funktion Grand Central Versand.

So etwas wie diesem Code:

@IBAction func buttonTapped(sender: AnyObject) { 
    asyncFunction() { 
     dispatch_async(dispatch_get_main_queue()) { 
      self.performSegueWithIdentifier("someID", sender: sender) 
     } 
    } 
} 

bearbeiten: Beachten Sie, dass in Swift 3 die Syntax geändert hat:

@IBAction func buttonTapped(_ sender: AnyObject) { 
    asyncFunction() { 
     DispatchQueue.main.async { 
      self.performSegueWithIdentifier("someID", sender: sender) 
     } 
    } 
} 

Ich hoffe, Sie, das hilft.

+0

Nun, ich habe das Segment in IB erstellt Strg ziehen von der Schaltfläche zum nächsten View-Controller, wie storniere ich die Überleitung Aktion, die Art von "hinter den Kulissen" ist? Wird das nicht immer noch ausgeführt? – u84six

+0

Was meinst du mit Abbrechen der Überfahrt? –

+0

Nun, wenn ich nur von der Schaltfläche ziehen, um Controller anzuzeigen, wird der Übergang passieren, wenn ich auf die Schaltfläche klicke. Dies passiert nicht in meinem Code. Es ist gegeben, wenn Sie die Verbindung herstellen (die Aktion, die ich ausgewählt habe, ist "Show"). – u84six

-4

Es klingt, als ob Sie es suchen, um synchron zu laufen; also, wenn Sie mit GCD Anruf dispatch_sync statt dispatch_async wenn sie auf dem Hintergrund-Thread, die schweres Heben setzen, und wenn Sie benötigen die Segue setzen die Dinge wieder auf den Hauptthread geschehen durch den Aufruf dispatch_sync(dispatch_get_main_queue(), ^{ // handle error or segue }

+0

Kann ich diesen Anruf tätigen und auch einen Wartetimer anzeigen? – u84six

+1

Sie können einen Wartetimer anzeigen, bevor Sie auf einen Hintergrundthread zugreifen und ihn entfernen, sobald sich die Dinge wieder im Hauptthread befinden. – aduflo

+0

@aduflo Was Sie sagten, es ist nicht der empfohlene Weg, das Problem zu lösen, asynchrone Aufrufe wurden hauptsächlich gemacht, um das Einfrieren zu vermeiden der Benutzeroberfläche. –

Verwandte Themen