Storyboard: Modal View Controller mit Unwind Segues schließen

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

  • Storyboard: Modal View Controller mit Unwind Segues schließen

    Hallo Leute,

    ich habe eine Frage zum Schließen eines Modal View Controllers via Storybard.

    Laut Dokumentation soll man im SourceViewController, dem ViewController, der den ModalViewController geöffnet hat, zwei IBActions deklarieren. Hier beispielsweise die cancel-Methode:

    Quellcode

    1. - (IBAction)cancel:(UIStoryboardSegue *)segue;
    2. {
    3. if ([segue.identifier isEqualToString:@"Cancel"]) {
    4. [self dismissViewControllerAnimated:YES completion:nil];
    5. }
    6. }

    Im InterfaceBuilder soll man dann die NavigationBarButtons mit dem Exit (steht für den SourceViewController des Segues, das den Model View Controller hervorruft, ist ein grünes Exit-Icon) verbinden.

    Für die done-Methode das gleiche, nur kann man hier eben noch zusätzlichen Code einbinden, um die Daten in den SourceViewController zu übertragen.
    Was mich jetzt aber verwundert, ist, dass die App den Modal View Controller auch schließt, wenn ich den Code nicht implementiere, sondern die Methode einfach nur leer lasse.

    Kann mir jemand erklären, wieso man die Methode dismissViewControllerAnimated:completion: aufrufen soll, wenn es auch ohne funktioniert? Oder gibt es einen noch einfacheren Weg, einen Modal View Controller ohne Delegation zu schließen?

    Mit freundlichen Grüßen

    TheFuriousLion


    Nachtrag: Diese Technik zum schließen des ModalViewController heißt übrigens Unwind Segues.

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von TheFuriousLion () aus folgendem Grund: Neuer Themenname, Nachtrag hinzugefügt, diverse Umformulierungen.

  • Meines Wissens kannst Du einen modalen Viewcontroller nicht durch einen Übergang schließen. Das machst Du mit einer ganz normalen Action

    Quellcode

    1. - (IBAction)cancel:(id)inSender{
    2. [self dismissViewControllerAnimated:YES completion:nil];
    3. }
    , die Du mit dem Button verbindest.

    Die Methode dismissViewControllerAnimated:completion: schließt übrigens den modalen Viewcontroller.
    „Meine Komplikation hatte eine Komplikation.“
  • Laut Dokumentation ist der ViewController, der den ModalViewController hervorgerufen hat, verantwortlich für dessen Schließung. Im Tutorial "Your Second iOS Application" wird das auch so gemacht.

    Im Header des MasterViewControllers habe ich zwei IBAction deklariert:

    Quellcode

    1. - (IBAction)cancel:(UIStoryboardSegue *)segue;
    2. - (IBAction)done:(UIStoryboardSegue *)segue;

    Dadurch, dass der Sender (segue) vom Typ UIStoryboardSegue ist, erkennt das Storyboard, wenn man einen Rechtsklick auf das Exit-Symbol macht die zwei Methoden. Das Exit steht wie schon gesagt für den ViewController, der den ModalViewController aufgerufen hat. In meinem Fall ist es der MasterViewController.

    Dann verbinde ich die zwei Buttons mit dem Exit (dem MasterViewController), weil ich dort die zwei IBActions deklariert habe, wie es die Dokumentation wünscht.

    Jetzt kommt es zur Implementierung der zwei Methoden.

    In diesen zwei Methoden sollte man dann dafür sorgen, dass der ModalViewController geschlossen wird, was die Methode dismissViewControllerAnimated:completion: machen sollte, richtig?

    Aber mein ModalViewController wird auch geschlossen, wenn ich die IBAction der zwei NavigationBarButtons an die leeren Methoden schicke:

    Quellcode

    1. - (void)cancel:(UIStoryboardSegue *)segue
    2. {
    3. }
    4. - (void)done:(UIStoryboardSegue *)segue
    5. {
    6. }

    Und ich kann im Internet und der Dokumentation einfach nichts finden, warum das so ist. Warum zeigt Apple im Tutorial, dass man die Methode dismissViewControllerAnimated:completion: aufrufen soll, wenn es auch ohne funktioniert.

    Falls ich das nicht gut genug erklärt habe, habe ich ein sehr einfaches Projekt angehängt, damit ihr das sehen könnt, was ich meine. Ich hoffe, ihr macht euch die Mühe und seht es euch kurz an.
  • Soweit ich gesehen habe, verfügt die App auch über einen Navigationcontroller. Unwind-Segues sind für den Rücksprung im Navigationstack gedacht und der Rücksprung ruft die Action-Methode auf. Wenn diese Methode nun ein Viewcontroller schließt, liegt doch diese Vermutung nahe, oder?
    „Meine Komplikation hatte eine Komplikation.“
  • Sorry, ich verstehe nicht ganz, was du mir sagen willst.

    Die App enthält einen UINavigationController als InitialViewController. Dieser wiederum enthält einen UITableViewController (MasterViewController).
    In der NavigationBar gibt es einen Button, der einen modalen ViewController öffnet. (ModalViewController) Dieser ist ein UINavigationController, der wieder einen UITableViewController beinhält. Und in dessen NavigationBar sind zwei Buttons, die für die Schließung des ModalViewControllers verantwortlich sind.

    Apple meint ja, dass der ViewController für die Schließung verantwortlich ist, der den modalen ViewController geöffnet hat. Deshalb habe ich die IBActions done: und cancel: im MasterViewController implementiert.

    So steht es im Tutorial und ich halte mich daran. Aber was mich nicht in Ruhe lässt, ist, warum der ModalViewController geschlossen wird, ohne dass die Methode dismissViewControllerAnimated:completion: aufgerufen wird.
  • Die Unwind-Segue springt nur automatisch im Navigationstack zurück. Da für den AddViewController jedoch ein neuer Navigationcontroller modal auf den existierenden Navigationstack gelegt wird, muss dieser beim Cancel auch wieder entfernt werden. Da die Unwind-Segue das nicht automatisch macht, brauchst Du den Aufruf der Methode dismissViewController:animated:completion:.
    „Meine Komplikation hatte eine Komplikation.“
  • Nein, das brauche ich nicht. Das verwundert mich auch so. Es funktioniert, aber warum?

    Im meinem Projekt, was ich hochgeladen habe, habe ich das Beispiel auf das nötigste Minimum reduziert, damit man leichter nachvollziehen kann, was vorgeht. Und du wirst sehen, dass es auch ohne dismissModalViewControllerAnimated:completion: funktioniert.

    Hat Apple das schon irgendwo programmiert? Wenn ja, warum steht dann im Tutorial, dass man den Code implementieren muss?

    Im Prinzip ist es mir egal, ob ich die eine Zeile mehr programmieren muss oder nicht, aber ich würde gerne wissen warum das so ist.
  • Weil meine App im Prinzip die gleiche App ist, nur mit anderen Daten, die eingegeben werden. Und wenn ich mich nicht irre, funktioniert es auch im Tutorial, ohne dass man den Code implementieren muss.


    Nachtrag:
    Ich habe nun endlich ein WWDC Video gefunden, das meine Frage klärt. Zum Video
    Laut Video übernimmt das Unwind Segue die Schließung, somit muss man sich nicht selbst um dessen Schließung kümmern. Ich finde es aber etwas seltsam, dass ein Anfänger Tutorial von Apple das "falsch" macht. Na ja, wenigstens ist das jetzt klar.
    Vielen Dank macmoonshine für deine Hilfe!

    Aber in diesem Fall ist es glaube ich besser, nur eine Action zu verwenden, denn sonst wäre die cancel:-Methode leer, was keinen Sinn ergibt. Und in der einen IBAction kann man dann ja den Segue Identifier abfragen und somit die zwei Buttons unterscheiden.

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von TheFuriousLion () aus folgendem Grund: Nachtrag hinzugefügt, Tippfehler.

  • Ich muss leider den alten Thread hier ausgraben...

    Ich gehe von einem View innerhalb eines NavigationController per MODAL auf ein neues view. Wenn ich dieses modalview jetzt mit "dismissViewControllerAnimated" schließe, klappt eig. alles wunderbar, nur:
    Die Steuerelemente in dem jetzt angezeigten View sind grau?! Wenn man sie anklickt werden sie blau und es klappt auch alles. Nur die Farbe/der state der buttons ist falsch? Warum?

    Danke