Erklärung zum Thema Segue

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Erklärung zum Thema Segue

    Hallo zusammen,

    derzeit arbeite ich mich in Objective-C ein um Apps für iOS zu programmieren. Ich habe zwei UIViewController mit einem Segue verbunden. Das funktioniert auch soweit sehr gut. Ich habe leider noch ein Verständnisproblem bei der folgenden Funktion :

    Quellcode

    1. - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
    2. {
    3. if ([segue.identifier isEqualToString:@"ShowFAQList"]) {
    4. NSIndexPath *indexPath = nil;
    5. indexPath = [self.CategoriesTableView indexPathForSelectedRow];
    6. FAQListViewController *flvc = segue.destinationViewController;
    7. flvc.title = self.CategoryName;
    8. flvc.category_id = [[self.ShowCategories objectAtIndex:indexPath.row]objectForKey:@"id"];
    9. return;
    10. }
    11. }
    Alles anzeigen

    Ab wann in dieser Funktion wird das viewDidLoad des FAQListViewControllers ausgeführt ?
  • matz schrieb:


    Nirgendwo, die Methode wird aufgerufen, wenn die View geladen ist.
    prepareForSegue beschreibt nur, was vor dem Triggern geschehen soll.


    MCDan schrieb:

    Innerhalb von prepareForSegue:sender: sicherlich nicht, da der ViewController ja noch nicht angezeigt wird.

    viewDidLoad wird bei dem ViewController erst aufgerufen, nachdem das XIB geladen wurde und der ViewController angezeigt werden soll.
    Ok, habe ich soweit verstanden. Das heißt also, ich bin noch sozusagen zwischen den beiden ViewControllern, aber der erste wird immer noch angezeigt.

    Thallius schrieb:

    Die Frage dürfte sein: "Warum willst du das wissen?"
    Ich habe auf beiden ViewControllern eine UITableView. Die zweite UITableView wird durch die Auswahl aus der ersten UITableView gefüllt. Ich wollte jetzt eine UIView mit ActivityIndicator einbauen, die während des Ladevorgangs für die Daten der zweiten UITableView angezeigt wird.

    Aber nach der Erklärung von MCDan und matz, muss ich diese UIVIew mit ActivityIndicator auf den zweiten UIViewController legen und die UIVIew dann über die viewDidLoad Funktion anzeigen lassen, während die Daten für die zweite UITableView geladen wird. So habe ich es zumindest von den Antworten her verstanden.
  • Erklärung zum Thema Segue

    Im Prinzip korrekt. Ich würde mir eine eigene Klasse für den actitivityview machen. Dann diesen mit einem addSubView auf den aktuellen ViewController legen. Anzeigen solltest du diesen aber nicht im viewDidLoad sondern im viewWillAppear oder viewDidAppear. Denn ich denke deine TableView wird ja bei jedem erscheinen des ViewControllers aktualisiert und nicht nur beim ersten. Dort gehört auch das Starten des Ladens der Daten für das Tableview rein. Wie gesagt. viewDidLoad wird nur beim ersten Mal aufgerufen. Danach bleibt der Controller im Speicher und wird wieder verwendet. Beim zweiten Aufruf wird viewDidLoad nicht mehrvaufgerufen. Deshalb ist das für deine Anwendung wahrscheinlich nicht der richtige Einstieg.
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
  • Thallius schrieb:

    Im Prinzip korrekt. Ich würde mir eine eigene Klasse für den actitivityview machen. Dann diesen mit einem addSubView auf den aktuellen ViewController legen. Anzeigen solltest du diesen aber nicht im viewDidLoad sondern im viewWillAppear oder viewDidAppear. Denn ich denke deine TableView wird ja bei jedem erscheinen des ViewControllers aktualisiert und nicht nur beim ersten.
    Danke für den Tipp, werde ich sofort umbauen.

    Thallius schrieb:

    Dort gehört auch das Starten des Ladens der Daten für das Tableview rein. Wie gesagt. viewDidLoad wird nur beim ersten Mal aufgerufen. Danach bleibt der Controller im Speicher und wird wieder verwendet. Beim zweiten Aufruf wird viewDidLoad nicht mehrvaufgerufen. Deshalb ist das für deine Anwendung wahrscheinlich nicht der richtige Einstieg.
    Das kann ich so nicht ganz nachvollziehen. Ich habe die App für iOS 7 erstellt und mein Inhalt wird in der zweiten UITableView aktualisiert, trotz dass ich alles im ViewDidLoad stehen habe im zweiten ViewController. Habe ich hier eventuell nur Glück ? 8)

    @MCDan : Ja die Daten erhalte ich als JSON.
  • RWarnecke schrieb:

    Thallius schrieb:

    Dort gehört auch das Starten des Ladens der Daten für das Tableview rein. Wie gesagt. viewDidLoad wird nur beim ersten Mal aufgerufen. Danach bleibt der Controller im Speicher und wird wieder verwendet. Beim zweiten Aufruf wird viewDidLoad nicht mehrvaufgerufen. Deshalb ist das für deine Anwendung wahrscheinlich nicht der richtige Einstieg.
    Das kann ich so nicht ganz nachvollziehen. Ich habe die App für iOS 7 erstellt und mein Inhalt wird in der zweiten UITableView aktualisiert, trotz dass ich alles im ViewDidLoad stehen habe im zweiten ViewController. Habe ich hier eventuell nur Glück ? 8)

    Nein, du hast nicht nur Glück. Der Controller bleibt nicht, wie Claus schreibt im Speicher, sondern der View bleibt, wenn er einmal geladen wurde, so lange im Speicher, wie der ViewController im Speicher bleibt. Bei deiner Konstellation wird ja sicherlich der zweite ViewController per Push-Segue auf den Stack eines NavigationControllers gepusht. Wenn du dann per Back-Button wieder zum ersten ViewController zurück gehst, wird der zweite ViewController wieder vom Stack gepoppt. Und weil dann niemand mehr eine starke (strong) Referenz mehr auf den zweiten ViewController hält, fliegt der aus dem Speicher und daher wird für einen erneute Anzeige der Controller und sein View wieder komplett neu geladen.
  • Erklärung zum Thema Segue

    Michael schrieb:

    RWarnecke schrieb:

    Thallius schrieb:

    Dort gehört auch das Starten des Ladens der Daten für das Tableview rein. Wie gesagt. viewDidLoad wird nur beim ersten Mal aufgerufen. Danach bleibt der Controller im Speicher und wird wieder verwendet. Beim zweiten Aufruf wird viewDidLoad nicht mehrvaufgerufen. Deshalb ist das für deine Anwendung wahrscheinlich nicht der richtige Einstieg.
    Das kann ich so nicht ganz nachvollziehen. Ich habe die App für iOS 7 erstellt und mein Inhalt wird in der zweiten UITableView aktualisiert, trotz dass ich alles im ViewDidLoad stehen habe im zweiten ViewController. Habe ich hier eventuell nur Glück ? 8)

    Nein, du hast nicht nur Glück. Der Controller bleibt nicht, wie Claus schreibt im Speicher, sondern der View bleibt, wenn er einmal geladen wurde, so lange im Speicher, wie der ViewController im Speicher bleibt. Bei deiner Konstellation wird ja sicherlich der zweite ViewController per Push-Segue auf den Stack eines NavigationControllers gepusht. Wenn du dann per Back-Button wieder zum ersten ViewController zurück gehst, wird der zweite ViewController wieder vom Stack gepoppt. Und weil dann niemand mehr eine starke (strong) Referenz mehr auf den zweiten ViewController hält, fliegt der aus dem Speicher und daher wird für einen erneute Anzeige der Controller und sein View wieder komplett neu geladen.


    Da hast du natürlich recht. Aber wehe er baut zu dem zweiten ViewController z.B. Noch einen DetailView in dem er die Daten ändern kann. Wenn er dann von diesem zum TableView zurück kehrt wird ersichtlich wundern warum die Daten nicht aktualisiert sind.
    Von daher finde ich viewWillAppear einfach die sauberere Lösung.

    Gruss

    Coaus
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
  • Ich würde sogar soweit gehen den Setter für category_id zu überschrieben und darin evtl. geladene Daten verwerfen und in viewWillAppear die Daten laden falls noch keine vorhanden sind.

    Damit wäre der ViewController dann sogar recycelbar, d.h. er müsste nicht bei jedem Aufruf neu erstellt werden sondern würde die Daten beim Verändern der category_id verwerfen und vor der Anzeige des ViewControllers neu laden.

    Aktuell wird der ViewController im StoryBoard immer neu erzeugt aber evtl. könnte Apple dies in Zukunft ja mal ändern und die ViewController vorhalten, falls diese noch einmal benötigt werden.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von MCDan ()

  • RWarnecke schrieb:

    Ja, es ist ein Push-Segue. Heißt es dann, ich habe alles richtig gemacht oder sollte ich doch die viewWillAppear oder viewDidAppear Funktionen nutzen ?

    Im Prinzip hast du nicht es nicht falsch gemacht, aber viewWillAppear: ist die bessere Lösung.

    Thallius schrieb:

    Da hast du natürlich recht. Aber wehe er baut zu dem zweiten ViewController z.B. Noch einen DetailView in dem er die Daten ändern kann. Wenn er dann von diesem zum TableView zurück kehrt wird ersichtlich wundern warum die Daten nicht aktualisiert sind.
    Von daher finde ich viewWillAppear einfach die sauberere Lösung.

    Dem stimme ich uneigeschränkt zu.
  • nur noch ein weiterer Tipp. Mit

    Quellcode

    1. [self performSegueWithIdentifier:@"ShowFAQList" sender:self];

    innerhalb einer Methode kannst Du programmatisch in die Methode prepareForSegue:sender: springen. Wird für dich vor allem dann interessant, wenn Du bald von der ersten View in weitere Views in Abhängigkeit von irgendwelchen gedrückten Knöpfen bzw. Zuständen springen willst. Wobei der Wert @"ShowFAQList" immer durch das jeweilige Identifier-Attribut im Storyboard.

    In der aufgerufenen Methode unterscheidst Du dann wie oben schon bei Dir

    Quellcode

    1. if ([segue.identifier isEqualToString:@"ShowFAQList"]) {
    2. // ..
    3. }
    4. else if ([segue.identifier isEqualToString:@"OtherIdentifierName"]) {
    5. // ..
    6. }


    Viel Spaß & Erfolg beim weiter Coden.
    ----
    Macht's gut und danke für den Fisch