Wie wird die Abwicklung programmgesteuert durchgeführt?


307

Mit Storyboard ist dies sehr einfach. Sie ziehen die Aktion einfach auf "Beenden". Aber wie soll ich es von meinem Code aus aufrufen?


33
Ich finde das eine berechtigte Frage - ich hatte es selbst. Sie können einen Abwicklungssegment programmgesteuert durchführen, indem Sie 1. einen manuellen Segue erstellen (Strg-Ziehen vom Dateibesitzer zum Beenden), 2. ihm in IB einen Namen geben und 3. einen normalen -performSegueWithIdentifier: sender: in Ihrem Code ausführen.
Yang Meyer

6
Sollte IMO nicht geschlossen worden sein. Die Benutzer, die für das Schließen dieser Frage gestimmt haben, scheinen keinen Obj-C / Cocoa Touch-Hintergrund zu haben.
LJ Wilson

Yang: Wie gibst du ihm einen Namen?
Sarfata

Ich benutze nur [self EntlassungViewControllerAnimated: YES Vervollständigung: Null]; programmgesteuert beenden. Ich weiß nicht, ob es der richtige Weg ist oder nicht.
Tangqiaoboy

1
sarfata: Sie erstellen zuerst eine "manuelle Abwicklung", indem Sie bei gedrückter Strg-Taste vom Ansichtscontroller auf "Beenden" ziehen. Dann finden Sie den Abschnitt in der Dokumentübersicht.
Huggie

Antworten:


283
  1. Erstellen Sie einen manuellen ctrlÜbergang ( -drag vom Dateibesitzer zum Beenden),
  2. Wählen Sie es im linken Controller-Menü unter der grünen EXIT-Schaltfläche.

Wählen Sie es im linken Controller-Menü unter der grünen EXIT-Schaltfläche

Geben Sie den Namen des Segues ein, um sich abzuwickeln.

Dann - (void)performSegueWithIdentifier:(NSString *)identifier sender:(id)sender.identifizieren Sie sich mit Ihrem Segue.


25
1) "File's Owner" - ist das nicht eine alte Terminologie? Es hat bei mir funktioniert, das Ziehen vom Ansichts-Controller zum Exit-Symbol zu steuern. 2) Obwohl es offensichtlich sein sollte, sucht Xcode nach einer Deklaration in der Schnittstelle der IBAction, die ein UIStoryboardSegue-Argument akzeptiert. In der Diskussion der WWDC 2012-Sitzung 407 wurde dies nicht erwähnt und der Code nicht eingefügt. Ohne ihn würde mein Exit-Symbol beim Ziehen mit gedrückter Ctrl-Taste nicht aktiv. 3) Es ist ziemlich cool, dass Sie am Ende Ihres großen roten Pfeils im Aktionsfeld den Pfeil "dorthin gehen" drücken können!
Tobinjim

71
Für alle, die wie ich immer noch Probleme mit der Umsetzung dieser Antwort haben, habe ich in diesem Repo eine ausführlichere Anleitung und ein Beispiel zusammengestellt: github.com/bradley/iOSUnwindSegueProgramatisch (Ich habe nicht versucht, für mich selbst zu werben, sondern nur meinen Kopf gegen die Wand geschlagen stundenlang dabei und ein funktionierendes Setup zu sehen hilft mir.)
Bradleygriffith

3
@bradleygriffith Du bist unglaublich super genial. Vielen Dank für die tolle Anleitung!
Eli_Rozen

7
@radleygriffith Ich wünschte, du hättest eine Antwort darauf gegeben, damit ich das auch markieren könnte! Ihr einzigartiger Beitrag bestand darin, festzustellen, welcher View Controller welchen Code erhält . Konnte das nirgendwo finden. Vielen Dank!
Aaron Vegh

3
Der Schlüssel für alle, die noch nicht darüber informiert sind, ist, dass sich die IBACTION in dem View-Controller befinden muss, zu dem Sie zurückkehren, und nicht in dem, in dem Sie sich gerade befinden. @Bradleygriffith schreibt dies auf GitHub, aber das habe ich nicht gesehen irgendwo anders erwähnt. Dieser Teil ist kritisch.
Axeva

163

Hier ist eine vollständige Antwort mit Ziel C und Swift:

1) Erstellen Sie einen IBActionAbwicklungsbereich in Ihrem Zielansichts-Controller (zu dem Sie wechseln möchten). Überall in der Implementierungsdatei.

// Objective C

    - (IBAction)unwindToContainerVC:(UIStoryboardSegue *)segue {

    }

// Swift

 @IBAction func unwindToContainerVC(segue: UIStoryboardSegue) {

    }

2) Ziehen Sie auf dem Quellansichts-Controller (dem Controller, von dem Sie wechseln) ⌃ + von "Name der Aktivität", um den Vorgang zu beenden. Sie sollten den in Schritt 1 erstellten Abwicklungsbereich im Popup sehen. (Wenn Sie es nicht sehen, lesen Sie Schritt eins). Wählen Sie unwindToContainerVC: aus dem Popup oder wie auch immer Sie Ihre Methode benannt haben, um Ihren Quellcontroller mit der Unwind-IBAction zu verbinden.

Geben Sie hier die Bildbeschreibung ein

3) Wählen Sie den Abschnitt in der Dokumentskizze des Storyboards des Quellansichts-Controllers aus (er wird unten aufgelistet) und geben Sie ihm eine Kennung .

Geben Sie hier die Bildbeschreibung ein

4) Aufruf der Abwickelstation segue diese Methode verwenden , Quelle View - Controller, Substituieren Ihre Abwickelstation segue Namen.

// Ziel c

[self performSegueWithIdentifier:@"unwindToContainerVC" sender:self];

// Schnell

self.performSegueWithIdentifier("unwindToContainerVC", sender: self)

NB. Verwenden Sie die sourceViewController-Eigenschaft des segue-Parameters für die Unwind-Methode, um auf alle exponierten Eigenschaften des Source-Controllers zuzugreifen. Beachten Sie außerdem, dass das Framework das Entlassen des Quellcontrollers behandelt. Wenn Sie dies bestätigen möchten, fügen Sie dem Quellcontroller eine Freigabemethode mit einer Protokollmeldung hinzu, die ausgelöst werden soll, sobald sie beendet wurde. Wenn der Dealloc nicht ausgelöst wird, haben Sie möglicherweise einen Aufbewahrungszyklus.


2
Mein Programm funktioniert nicht, nicht einmal aufgerufen(IBAction)unwindToContainerVC:(UIStoryboardSegue *)segue
xhg

2
Diese Lösung funktioniert nicht, wenn der View-Controller, zu dem Sie sich abwickeln, nur in Ihrem Storyboard vorhanden ist, auch bekannt als keine benutzerdefinierte Code-Implementierung
mnl

@mnl weiß nicht genau, was du sagst, aber es funktioniert mit Storyboard-Szenen oder Schreibfedern. Wenn Sie eine Viewcontroller-Szene im Code erstellen, würden Sie keine Methoden verwenden, die IB in ihrem Namen "zurückgeben", was ohnehin nichtig ist, da diese dem Zweck der Kommunikation zwischen Code und IB dienen. Adressiert das Ihren Kommentar?
smileBot

1
Ihr Bild mit dem ctrl+dragvon ViewControllerbis Exitwar unglaublich hilfreich. Vielen Dank!
Kbpontius

Für Swift 4.2 verwenden Sie: self.performSegue (withIdentifier: "unwindToVC", Absender: self)
Reefwing

81

bradleygriffithDie Antwort war großartig. Ich habe Schritt 10 gemacht und zur Vereinfachung einen Screenshot gemacht. Dies ist ein Screenshot in Xcode 6.

  1. Ziehen Sie bei gedrückter Ctrl-Taste vom orangefarbenen Symbol zum roten Beenden-Symbol, um eine Abwicklung ohne Aktionen / Schaltflächen in der Ansicht zu erstellen.

Geben Sie hier die Bildbeschreibung ein

  1. Wählen Sie dann unwind seguein der Seitenleiste Folgendes aus:

Geben Sie hier die Bildbeschreibung ein

  1. Legen Sie eine Segue Identifier-Zeichenfolge fest:

Geben Sie hier die Bildbeschreibung ein

  1. Greifen Sie über den Code auf diese Kennung zu:
[self performSegueWithIdentifier:@"unwindIdentifier" sender:self];

4
Zunächst muss die Methode zum Abwickeln in die UIViewController. Dann wird Ihre Lösung funktionieren
Alex Cio

5
und Sie müssen Identifier auf diesen neuen Abschnitt setzen! Vergiss es nicht.
Kraag22

1
Ist es möglich, die "Exit" -Verbindung im Source View Controller programmgesteuert herzustellen?
Andrew Kirna

13

Ich habe verwendet, [self dismissViewControllerAnimated: YES completion: nil];was Sie zur Berufung zurückbringen wird ViewController.


6
Larry, das ist ein absolut gültiger Ansatz, wenn Sie zum vorherigen Ansichts-Controller zurückkehren möchten, dh zu dem, der denjenigen präsentiert hat, den Sie gerade beenden. Die Frage wurde gestellt, weil neu in Xcode 4.5 die Möglichkeit ist, sich von einem Ansichts-Controller irgendwo in der Präsentationsreihenfolge zu einem viel früheren Ansichts-Controller zu "entspannen". Weitere Informationen finden Sie in der WWDC 2012-Sitzung 407.
Tobinjim

11

Zitieren von Text aus Apples technischem Hinweis zum Abwickeln von Segmenten: Um einen Abwicklungsbereich hinzuzufügen, der nur programmgesteuert ausgelöst wird, steuern und ziehen Sie vom View Controller-Symbol der Szene zum Ausgangssymbol und wählen Sie dann eine Abwicklungsaktion für den neuen Abschnitt aus dem Popup-Menü aus.

Link zum technischen Hinweis


6

Die obige Antwort von Vishal Chaudhry hat bei mir funktioniert. Ich würde das auch hinzufügen, um die Sequenz manuell auszulösen, indem ich:

[self performSegueWithIdentifier:@"mySegueName" sender:self];

Im ViewController müssen Sie auch den Abwicklungsbereich unter der ViewController-Szene im Storyboard und in der Eigenschaftenansicht auf der rechten Seite auswählen. Stellen Sie sicher, dass das Feld "Indentifier" den Namen enthält, auf den Sie sich im Code beziehen ("mySegueName" im obigen Beispiel) ).

Wenn Sie diesen Schritt weglassen, wird in der obigen Zeile eine Ausnahme ausgelöst, dass der Name der Sequenz nicht bekannt ist.


3

Abwärtskompatible Lösung, die für Versionen vor ios6 funktioniert, für Interessenten:

- (void)unwindToViewControllerOfClass:(Class)vcClass animated:(BOOL)animated {

    for (int i=self.navigationController.viewControllers.count - 1; i >= 0; i--) {
        UIViewController *vc = [self.navigationController.viewControllers objectAtIndex:i];
        if ([vc isKindOfClass:vcClass]) {
            [self.navigationController popToViewController:vc animated:animated];
            return;
        }
    }
}

2
Entspannen Sie Segues, um viel mehr zu tun, als zu einer bestimmten Klasse in einem Navigations-Controller-Stack zurückzukehren.
Steve Moser

2

SWIFT 4 :

1. Erstellen Sie eine @IBAction mit einem Übergang innerhalb des Controllers, zu dem Sie sich entspannen möchten:

    @IBAction func unwindToVC(segue: UIStoryboardSegue) {

    }

2. Im Storyboard möchten Sie vom Controller aus Strg + Ziehen vom Controller-Zeichen zum Beenden des Zeichens trennen (abwickeln) und die zuvor erstellte Methode auswählen:

Geben Sie hier die Bildbeschreibung ein

3. Jetzt können Sie feststellen, dass Sie in der Dokumentkontur eine neue Zeile mit dem Titel "Segel abwickeln ..." haben. Jetzt sollten Sie auf diese Zeile klicken und den Attributinspektor öffnen, um die Kennung festzulegen (in meinem Fall unwindSegueIdentifier ).

Geben Sie hier die Bildbeschreibung ein

4. Du bist fast fertig! Jetzt müssen Sie den View Controller öffnen, von dem Sie sich abwickeln möchten, und eine Methode erstellen, die eine Übergabe ausführt. Sie können beispielsweise eine Schaltfläche hinzufügen, sie mit dem Code mit @IBAction verbinden und anschließend in dieser IBAction die Methode perfromSegue (withIdentifier: sender :) hinzufügen :

     @IBAction func unwindToSomeVCWithSegue(_ sender: UIButton) {
         performSegue(withIdentifier: "unwindSegueIdentifier", sender: nil)
     }

Das ist alles was Sie tun müssen!


Ist es möglich, die "Exit" -Verbindung im Source View Controller programmgesteuert herzustellen?
Andrew Kirna

1

Swift 4.2, Xcode 10+

Für diejenigen, die sich fragen, wie dies mit VCs gemacht werden soll, die nicht über das Storyboard eingerichtet wurden (diejenigen, die zu dieser Frage kommen, indem sie "programmatisch" + "sewind segue" suchen).

Da Sie eine Abwicklungssegmentierung nicht programmgesteuert einrichten können, besteht die einfachste rein programmatische Lösung darin, Folgendes aufzurufen:

navigationController?.popToRootViewController(animated: true)

Dadurch werden alle Ansichts-Controller auf dem Stapel wieder auf Ihren Root-Ansichts-Controller verschoben.


Verwenden Sie Folgendes, um nur den obersten Ansichts-Controller aus dem Navigationsstapel zu entfernen:

navigationController?.popViewController(animated: true)


1
Das ist normalerweise mehr als Sie möchten - um einen zurückzuschieben, tun Sie einfach: [self.navigationController popViewControllerAnimated: YES];
Andy Weinstein

In der Tat habe ich das zu meiner Antwort hinzugefügt - danke @AndyWeinstein
10623169

0

Zu Ihrer Information: Damit die Antwort von @ Vadim mit einer manuellen Abwicklungssequenzaktion funktioniert, die von einem View Controller aus aufgerufen wird, müssen Sie den folgenden Befehl eingeben:

[self performSegueWithIdentifier:(NSString*) identifier sender:(id) sender];

innerhalb der überschriebenen Klassenmethode viewDidAppear wie folgt :

-(void) viewDidAppear:(BOOL) animated
{
    [super viewDidAppear: animated];

    [self performSegueWithIdentifier:@"SomeSegueIdentifier" sender:self];
}

Wenn Sie es in andere ViewController-Methoden wie viewDidLoad oder viewWillAppear einfügen , wird es ignoriert.


3
Auf jeden Fall falsch. Rufen Sie performSegueWithIdentifier von jedem beliebigen Ort aus auf.
smileBot

Würde dies nicht einfach eine Abwicklung durchführen, sobald die Ansicht geladen wird? Anstatt zu spielen, wann SIE wollen, zum Beispiel nach einem Knopfdruck.
Pahnev

@Pahnev ja das würde es. Ich weiß nicht, wie diese Antwort zu positiven Stimmen kam. Das Aufrufen performSegueWithIdentfierbewirkt genau das: Durchführen des Übergangs von einem ViewController zu einem anderen
Ezcoding

Komplett falsch. Es würde beim Start sofort zurückgespult.
Lee Probert
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.