Nehmen wir an, wir haben drei View-Controller: 1, 2 und 3. Mit dem Storyboard ist es ziemlich einfach, vom View-Controller 3 auf Controller 1 über ein Abwicklungssegment zu wechseln. Beim Abwickeln ist der View-Controller 2 jedoch kurz sichtbar, bevor der View-Controller 1 angezeigt wird. Gibt es eine Möglichkeit, von 3 zu 1 zu kommen, ohne 2 erneut anzuzeigen?
Controller 1 anzeigen:
%Vor%Controller 2 anzeigen:
%Vor%View Controller 3:
%Vor%Dies erzeugt die folgenden Protokollmeldungen:
Ich habe versucht, benutzerdefinierte Segmente zu verwenden und die Animation zu deaktivieren. Obwohl das Entfernen der Animation den View-Controller 2 für einen noch kürzeren Zeitraum erscheinen lässt, wird er immer noch angezeigt. Gibt es eine Möglichkeit, dieses Verhalten zu programmieren?
Screenshot des Storyboards:
Joshs Antwort führte mich zu einer Lösung. Gehen Sie folgendermaßen vor:
Erstellen Sie einen Root-UINavigationController, und weisen Sie ihn einer Klasse zu, die UINavigationController erweitert und die Methode "segueForUnwindingToViewController: fromViewController: identifier" überschreibt. Dies könnte bei Bedarf durch die Kennung gefiltert werden.
CustomNavigationController:
%Vor%Erstellen Sie ein benutzerdefiniertes Push-Segment, das sich wie ein Modal-Segment verhält, jedoch unseren Navigationscontroller verwendet. Verwenden Sie dies für alle "Push" -Segmente.
CustomPushSegue:
%Vor%Erstellen Sie ein benutzerdefiniertes Abwicklungssegment, das den Navigationscontroller verwendet, um zum Ziel zu gelangen. Dies wird von unserem Navigationscontroller im segueForUnwindingToViewController aufgerufen: fromViewController: identifier-Methode.
CustomUnwindSegue:
%Vor%Bei Verwendung einer Kombination dieser Muster erscheint der zweite Ansichts-Controller während des Abwicklungsvorgangs nie.
Neue Protokollausgabe:
Ich hoffe, das hilft jemand anderem mit dem gleichen Problem.
Dies liegt daran, dass Abwicklungssegmente nach dem nächsten View-Controller suchen, der die Abwicklungsaktion implementiert, die Sie im Storyboard angegeben haben. Aus der Dokumentation :
Wie ein Abwicklungssegment ausgewählt wird, wählt sein Ziel
Wenn ein Abwicklungssegment ausgelöst wird, muss er den nächsten View-Controller finden, der die Abwicklungsaktion implementiert, die beim Definieren des Abwicklungssegments festgelegt wurde. Dieser View-Controller wird zum Ziel des Abwicklungssegments. Wenn kein geeigneter View-Controller gefunden wird, wird der Abwicklungs-Abschnitt abgebrochen. Die Suchreihenfolge ist wie folgt:
Eine
viewControllerForUnwindSegueAction:fromViewController:withSender:
-Nachricht wird an das übergeordnete Element des Quellansicht-Controllers gesendet.Eine
viewControllerForUnwindSegueAction:fromViewController:withSender:
Nachricht wird an den nächsten übergeordneten View-Controller gesendet [...]Sie können canPerformUnwindSegueAction überschreiben: fromViewController: withSender: Wenn Sie bestimmte Anforderungen haben, ob Ihr View Controller eine Abwicklungsaktion verarbeiten soll.
Die View-Controller in Ihrem Beispiel haben kein Elternteil, daher scheint das Fallback (für das ich keine Dokumentation sehen kann) darin, jedes presentingViewController
zu instanziieren und% co_de aufzurufen % auf ihnen der Reihe nach. Die Rückgabe von canPerformUnwindSegueAction
von dieser Methode in NO
verhindert nicht die Instanziierung und Anzeige, so dass das Problem nicht gelöst wird.
Ich habe versucht, Ihren Code in einen Navigationscontroller eingebettet, und es funktioniert gut. Dies liegt daran, dass in diesem Fall ViewControllerTwo
das übergeordnete Element jedes Ihrer View-Controller ist und alle Auswahl eines Zielansicht-Controllers verarbeitet. Weitere Dokumentation:
Containeransicht-Controller
Containeransicht-Controller haben zwei Verantwortlichkeiten beim Abwicklungsvorgang, die beide im Folgenden erläutert werden. Wenn Sie die vom SDK bereitgestellten Container-View-Controller verwenden, z. B. UINavigationController, werden diese automatisch verarbeitet.
Wenn Sie einen einfachen Container-View-Controller als übergeordnetes Element für Ihre drei View-Controller erstellen möchten, können Sie mithilfe seiner UINavigationController
-Methode jeden untergeordneten Controller auf das Vorhandensein der Abwicklungsaktion prüfen, bevor er% aufruft. co_de% auf diesem Controller und schließlich die erste von denen, die viewControllerForUnwindSegueAction
zurückgibt.
Auswählen eines untergeordneten Ansichtscontrollers zum Abwickeln einer Aktion zum Abwickeln
Wie in Wie ein Abwicklungssegueg angegeben ist, wird der Quellansicht-Controller eines Abwicklungssegments auf sein übergeordnetes Element festgelegt, um einen Ansichtscontroller zu finden, der die Abwicklungsaktion verarbeiten möchte. Ihr Containeransicht-Controller sollte die in Listing 2 gezeigte Methode überschreiben, um die untergeordneten Ansichtscontroller nach einem Ansichtscontroller zu durchsuchen, der die Abwicklungsaktion verarbeiten soll. Wenn keiner der Child-View-Controller eines Containers die Abwicklungsaktion verarbeiten soll, sollte die Superimplementierung aufgerufen und das Ergebnis zurückgegeben werden.
Ein Containeransicht-Controller sollte seine untergeordneten Elemente auf eine Weise durchsuchen, die für diesen Container sinnvoll ist. Zum Beispiel durchsucht UINavigationController rückwärts durch sein Array viewControllers, beginnend mit der Ansicht am oberen Rand des Navigationsstapels.
Listing 2 Überschreiben Sie diese Methode, um einen Ansichtscontroller zurückzugeben, der die Abwicklungsaktion verarbeiten soll. - (UIViewController *) viewControllerForUnwindSegueAction: (SEL) Aktion vonViewController: (UIViewController *) vonViewController withSender: (ID) Absender
Container view controller design hat einen ganzen Artikel , der von Apple dafür vorgesehen ist , die ich hier nicht kopieren werde (mehr als genug von Apples Schreiben in dieser Antwort bereits!), aber es sieht so aus, als würde es einige Überlegungen brauchen, um es richtig zu machen, da es von der genauen Rolle abhängt, die diese in Ihrer Anwendung spielen sollen .
Eine schnelle Problemumgehung, um Ihr gewünschtes Verhalten mithilfe von Abwicklungssegmenten zu erzielen, könnte darin bestehen, die Ansichtscontroller in canPerformUnwindSegueAction
einzubetten und dann die Navigationsleiste mithilfe von
Sieht so aus, als ob Custom-Sequences verwendet werden, also ist es möglich, dass das irgendwie stört, obwohl ich es nie gesehen habe. Ich schlage vor, Sie sehen sich Apples Beispielprojekt an. Es hat auch benutzerdefinierte Segmente darin, so sollte es als ein guter Ausgangspunkt für Sie dienen.
Ich bin überrascht, dass Sie das Verhalten sehen, das Sie sehen, aber eine Möglichkeit, dies zu ändern, wäre die Verwendung eines expliziten Abbruchs anstelle von Abwicklungssegmenten (dies setzt voraus, dass die Weiterleitungssegmente modal sind).
Alles wird gut aussehen, wenn VC1 das tut:
%Vor%Oder wenn ein anderer VC das tut:
%Vor%Das einzige Problem ist, dass Sie ein Handle für vc1 benötigen, wenn Sie von einem anderen vc ablehnen wollen. Sie könnten ein delegate-Muster verwenden, um vc1 mitzuteilen, dass es die Kündigung ausführen sollte, aber eine einfachere Lösung besteht darin, dass vc2 oder 3 eine Benachrichtigung posten, wenn die Abwicklung stattfinden soll.
VCs 2 oder 3 können dies tun:
%Vor%Und VC1 kann dies tun:
%Vor%Tags und Links objective-c iphone ios xcode uistoryboardsegue