2016-06-29 6 views
0

empfangen sind habe ich eine Schaltfläche in einer Zelle, die ein Protokoll aufruft, die Daten hat, die durch den Übergang zu den View-Controller übergeben werden muss. Der Übergang geschieht durch das Storyboard. Mein aktueller Code verwendet die shouldperformsegue, um Nein zurückzugeben, wenn die Taste gedrückt wird, da das erste Segment, das passiert, die Daten nicht enthält. Ich rate das Segment und das Protokoll werden asynchron behandelt.Wie segue auszuführen, nachdem Informationen aus Protokoll

Aber bevor ich keine Rückkehr sagen, dass ich den Übergang zu einer Verzögerung durchzuführen. Dieser verzögerte Übergang hat die Daten und funktioniert gut.

Meine Frage ist es eine Möglichkeit, für das Protokoll zu warten, zu beenden und dann den Übergang durchführen? Vielleicht mit einem Ausführungsblock?

Antwort

0

Die anderen Responder haben darüber angedeutet, aber haben es nicht ausdrücklich erwähnt, geht so hier.

Sie einen Übergang direkt auf die Schaltfläche nicht binden. Ziehen Sie stattdessen bei gedrückter Strg-Taste vom Quell-View-Controller SCENE zur Ziel-Szene, um auf der View-Controller-Ebene ein Segment zu erstellen. Geben Sie dem Segment einen eindeutigen Bezeichner.

Dann in Ihrer Schaltfläche IBAction Code, tut dem Asynchron-Netzwerk herunterladen. Möglicherweise möchten Sie während des Downloads eine Meldung "Laden, Bitte warten" oder etwas anzeigen. Die meisten async Netzwerkaufrufe nehmen einen Abschlussblock. Verteilen Sie in diesem Abschlussblock einen Anruf an performSegueWithIdentifier in einem Aufruf an dispatch_async(dispatch_get_main_queue(), damit das Segment im Hauptthread aufgerufen wird. (@ Santaclaus Antwort zeigt die Syntax für die.)

So Ihrer Schaltfläche IBAction Code könnte wie folgt aussehen:

- (IBAction) buttonAction: (UIButton *) sender; 
{ 
    //Display a "please wait"message to the user if desired 
    doAsyncCallTakingBlock(completion: ^(NSData *data) 
    { 
    //parse the data, (or whatever) 

    dispatch_async(dispatch_get_main_queue(),^
    { 
     //This call uses the button as the sender. That might be appropriate, 
     //or not. 
     [self performSegueWithIdentifier:@"jumpToOtherViewController" 
     sender: sender]; 
    }); 
    } 
} 

Mit diesem Ansatz wird der Übergang erst die Asynchron-Methode aufgerufen (die ich rief doAsyncCallTakingBlock in meinem Beispielcode) hat seine Arbeit beendet. Sie können eine Alamofire-Anforderungsmethode, eine NSURLSession oder eine andere asynchrone Methode aufrufen, die einen Abschlussblock verwendet.

+0

Es hätte mir nichts ausgemacht, dass du meinen 'dispatch_async' Block gestohlen hättest, wenn es nicht deinen hässlichen geschweiften Klammerstil hätte ...: P –

+0

Nein, ich habe deine hässliche Formatierung korrigiert. :) Ich bin ein [** Allman Mann **] (https://en.wikipedia.org/wiki/Indent_style#Allman_style), durch und durch. –

+0

@SantaClaus, Ich gab Ihnen Anerkennung dafür, dass ich der erste war, der den dispatch_async-Code posten konnte. :) –

0

Check out performSegueWithIdentifier auf UIViewController. Wenn Sie einen Übergang zwischen den View-Controllern in Ihrem Storyboard einrichten (nicht über die Schaltfläche) und ihm eine Kennung geben, können Sie den Übergang durchführen, sobald die Daten bereit sind.

Da Sie erwähnt, dass Ihre Daten asynchron sein holen sind, können Sie wie so den performSegueWithIdentifier Aufruf an den Haupt-Thread versenden müssen möglicherweise:

dispatch_async(dispatch_get_main_queue(), ^{ 
    [self performSegueWithIdentifier:@"jumpToOtherViewController" sender:self]; 
}); 

Um die Daten tatsächlich auf die nächsten View-Controller übergeben Sie, kann prepareForSegue wie beschrieben here verwenden.

+0

Was ist mit dem Übergang, der passiert, wenn ich auf den Knopf klicke? Löse ich es einfach einfach ab? –

+0

@cityparking Dieses Segment löschen. Du wirst es nicht mehr benutzen. Verknüpfen Sie stattdessen die Schaltfläche mit einer '@ IBAction', die den Datenabruf startet. Wenn der Datenabruf beendet ist, rufen Sie 'performSegueWithIdentifier' wie gezeigt auf. –

+0

@cityparking Außerdem habe ich gerade den Code in Objective-C geändert. Das tut mir leid. –

0

Ja, ich würde Blöcke verwenden. Zum Beispiel:

[Api getDataWithCompletion:^(BOOL success, NSString *data) { 
    if (success) { 
     self.data = data; 
     [self performSegueWithIdentifier:@"MySegue" sender:self]; 
    } else { 
     NSLog(@"Failed to get data"); 
    } 
}]; 

Dann es auf den nächsten View-Controller zu übergeben:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 
    if ([segue.identifier isEqualToString:@"MySegue"]) { 
     TargetViewController *targetVC = (TargetViewController*)segue.destinationViewController; 
     targetVC.data = self.data; 
    } 
} 
Verwandte Themen