Jak programowo wykonać odwijanie segue?


307

Korzystanie z scenorysu jest bardzo proste. Po prostu przeciągnij akcję do „Wyjdź”. Ale jak mam to nazwać z mojego kodu?


33
Uważam to za ważne pytanie - sam to miałem. Możesz wykonać odwijanie segue programowo: 1. tworząc ręczny segue (przeciągnij ctrl z Właściciela pliku do wyjścia), 2. nadając mu nazwę w IB, a następnie 3. wykonując normalny -performSegueWithIdentifier: sender: w kodzie.
Yang Meyer

6
Nie powinno być zamknięte IMO. Użytkownicy, którzy głosowali za zamknięciem tego pytania, z pewnością nie mają tła Obj-C / Cocoa Touch.
LJ Wilson

Yang: Jak to się nazywa?
sarfata

Po prostu używam [self dismissViewControllerAnimated: TAK zakończenie: zero]; wyjść programowo. Nie wiem, czy to właściwa droga, czy nie.
tangqiaoboy

1
sarfata: Najpierw tworzysz „segregowanie ręczne” przeciągając klawiszem Ctrl z viewcontroller do „Exit”. Następnie możesz znaleźć segue w zarysie dokumentu.
huggie

Odpowiedzi:


283
  1. Utwórz ręczny segue ( ctrl-drag od właściciela pliku do wyjścia),
  2. Wybierz go w menu lewego kontrolera poniżej zielonego przycisku EXIT.

Wybierz go w menu lewego kontrolera poniżej zielonego przycisku EXIT

Wstaw nazwę segmentu, aby się zrelaksować.

Następnie - (void)performSegueWithIdentifier:(NSString *)identifier sender:(id)sender.z identyfikatorem segue.


25
1) „Właściciel pliku” - czy to nie stara terminologia? Sprawdziłem przeciąganie z kontrolera widoku do ikony wyjścia. 2) Chociaż powinno to być oczywiste, Xcode szuka deklaracji w interfejsie IBAction, która przyjmuje argument UIStoryboardSegue; w sesji 407 sesji WWDC 2012 nie wspomniano o tym i nie wklejono tego kodu. Bez tego moja ikona wyjścia nie uaktywniałaby się podczas przeciągania do niej kontrolki. 3) To całkiem fajne, że na końcu dużej czerwonej strzałki w polu Akcja możesz nacisnąć strzałkę „idź tam”!
tobinjim,

71
Dla każdego, kto, podobnie jak ja, nadal ma problem z implementacją tej odpowiedzi, przygotowałem dokładniejszy przewodnik i przykład w tym repozytorium: github.com/bradley/iOSUnwindSegueProgramatically (Nie próbując się reklamować, po prostu uderzyłem głową w ścianę godzinami na ten temat pomaga mi zobaczenie działającej konfiguracji).
bradleygriffith

3
@bradleygriffith Jesteś niesamowicie super niesamowity. Dzięki za świetny przewodnik!
Eli_Rozen

7
@bradleygriffith Chciałbym, żebyś udzielił odpowiedzi, żebym mógł to zaznaczyć! Twój unikalny wkład polegał na ustaleniu, który kontroler widoku otrzymuje jaki kod . Nigdzie nie mogłem tego znaleźć. Dzięki!
Aaron Vegh,

3
Kluczem dla każdego, kto nadal się na tym boryka, jest to, że IBACTION musi znajdować się w kontrolerze widoku, do którego wracasz, a nie w tym, w którym obecnie się znajdujesz. @Bradleygriffith pisze to na GitHub, ale nie widziałem tego wymienione gdziekolwiek indziej. Ta część jest krytyczna.
Axeva,

163

Oto pełna odpowiedź na temat celu C i Swift:

1) Utwórz IBActionodwijany segment w docelowym kontrolerze widoku (do którego chcesz segregować). W dowolnym miejscu pliku implementacji.

// Objective C

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

    }

// Swift

 @IBAction func unwindToContainerVC(segue: UIStoryboardSegue) {

    }

2) Na kontrolerze widoku źródłowego (kontrolerze, z którego segregujesz), ⌃ + przeciągnij z „Nazwa działania”, aby wyjść. W wyskakującym okienku powinien zostać wyświetlony segment odwijania utworzony w kroku 1. (Jeśli go nie widzisz, przejrzyj krok pierwszy). Wybierz unwindToContainerVC: z wyskakującego okienka lub jakkolwiek nazwałeś swoją metodę połączenia kontrolera źródłowego z odprężającym IBAction.

wprowadź opis zdjęcia tutaj

3) Wybierz segue w konspekcie dokumentu kontrolera widoku źródłowego scenorysu (zostanie wymieniony u dołu) i podaj mu identyfikator .

wprowadź opis zdjęcia tutaj

4) Wywołaj odwijanie segue przy użyciu tej metody z kontrolera widoku źródłowego , zastępując nazwę odwijania segue.

// Cel C

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

// Szybki

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

NB Użyj właściwości sourceViewController parametru segue w metodzie unwind, aby uzyskać dostęp do wszystkich odsłoniętych właściwości kontrolera źródłowego. Zauważ też, że framework obsługuje zamykanie kontrolera źródłowego. Jeśli chcesz to potwierdzić, dodaj do kontrolera źródłowego metodę dealloc z komunikatem dziennika, który powinien zostać uruchomiony po zabiciu. Jeśli dealloc nie strzela, możesz mieć cykl zatrzymania.


2
Mój program nie działa, nawet nie jest wywoływany(IBAction)unwindToContainerVC:(UIStoryboardSegue *)segue
xhg

2
to rozwiązanie nie działa, gdy kontroler widoku, do którego nie chcesz się przyzwyczaić, istnieje tylko w twojej serii ujęć, aka nie ma niestandardowego wdrożenia kodu
mnl

@ mnl nie jestem pewien, co mówisz, ale działa ze scenami scenariuszy lub stalówkami. Jeśli tworzysz scenę kontrolera widoku w kodzie, nie użyłbyś żadnych metod, które „zwrócą” IB w ich nazwie, co i tak jest naprawdę nieważne, ponieważ służą one do komunikacji między kodem a IB. Czy to odnosi się do twojego komentarza?
smileBot

1
Twoje zdjęcie pokazujące ctrl+dragod ViewControllerdo do Exitbyło niezwykle pomocne. Dzięki!
kbpontius

W przypadku wersji Swift 4.2: self.performSegue (withIdentifier: „unwindToVC”, nadawca: self)
Reefwing

81

bradleygriffithodpowiedź była świetna. Zrobiłem krok 10 i zrobiłem zrzut ekranu dla uproszczenia. To jest zrzut ekranu w Xcode 6.

  1. Przeciągnij z wciśniętym klawiszem Control od pomarańczowej ikony do czerwonej ikony Wyjdź, aby utworzyć odprężenie bez żadnych działań / przycisków w widoku.

wprowadź opis zdjęcia tutaj

  1. Następnie wybierz unwind seguena pasku bocznym:

wprowadź opis zdjęcia tutaj

  1. Ustaw ciąg identyfikatora segmentu:

wprowadź opis zdjęcia tutaj

  1. Uzyskaj dostęp do tego identyfikatora z kodu:
[self performSegueWithIdentifier:@"unwindIdentifier" sender:self];

4
Po pierwsze, metoda odwijania musi być zawarta wewnątrz UIViewController. Wtedy twoje rozwiązanie zadziała
Alex Cio

5
i musisz ustawić Identyfikator dla tego nowego segmentu! Nie zapomnij o tym.
kraag22

1
Czy można programowo utworzyć połączenie „wyjściowe” w kontrolerze widoku źródłowego?
Andrew Kirna

13

Użyłem, [self dismissViewControllerAnimated: YES completion: nil];co spowoduje powrót do połączenia ViewController.


6
Larry, jest to całkowicie poprawne podejście, jeśli chcesz powrócić do poprzedniego kontrolera widoku, tj. Tego, który przedstawiał ten, z którego właśnie wychodzisz. Pojawiło się pytanie, ponieważ nowością w Xcode 4.5 jest możliwość „odpoczynku” jednego kontrolera widoku gdzieś w kolejności prezentacji do znacznie wcześniejszego kontrolera widoku. Szczegółowe informacje można znaleźć w sesji 407 WWDC 2012.
tobinjim,

11

Cytując tekst z uwagi technicznej Apple na temat odwijania segmentu: Aby dodać odwijany segment, który będzie uruchamiany tylko programowo, steruj + przeciągnij z ikony kontrolera widoku sceny do ikony wyjścia, a następnie wybierz akcję odwijania dla nowego segmentu z menu podręcznego.

Link do uwagi technicznej


6

Powyższa odpowiedź Vishala Chaudhry'ego działała na mnie. Dodałbym również, aby ręcznie uruchomić seque przy użyciu:

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

z poziomu ViewController należy również wybrać segregację odwijania w ramach Sceny ViewController w serii ujęć, a w widoku właściwości na RHS upewnić się, że pole Indentifier zawiera nazwę, do której się odwołujesz w kodzie („mySegueName” w powyższym przykładzie ).

Jeśli pominiesz ten krok, powyższa linia zgłosi wyjątek, że nazwa seque nie jest znana.


3

Zgodne wstecz rozwiązanie, które będzie działać w wersjach wcześniejszych niż ios6, dla zainteresowanych:

- (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
Sekwencje Unwind robią znacznie więcej niż powrót do określonej klasy na stosie kontrolera nawigacyjnego.
Steve Moser

2

SWIFT 4 :

1. Utwórz @IBAction z segue wewnątrz kontrolera, w którym chcesz się zrelaksować:

    @IBAction func unwindToVC(segue: UIStoryboardSegue) {

    }

2. W serii ujęć, z kontrolera, który chcesz oddzielić (odwijaj) od ctrl + przeciągnij ze znaku kontrolera, aby wyjść i wybierz metodę, którą utworzyłeś wcześniej:

wprowadź opis zdjęcia tutaj

3. Teraz możesz zauważyć, że w konspekcie dokumentu masz nową linię z tytułem „Unwind segue ....”. Teraz powinieneś kliknąć tę linię i otworzyć inspektora atrybutów, aby ustawić identyfikator (w moim przypadku unwindSegueIdentifier ).

wprowadź opis zdjęcia tutaj

4. Jesteś prawie gotowy! Teraz musisz otworzyć kontroler widoku, z którego chcesz się zrelaksować i stworzyć metodę, która wykona segue. Na przykład możesz dodać przycisk, połączyć go z kodem za pomocą @IBAction , a następnie w tym IBAction dodać perfromSegue (withIdentifier: sender :) metoda:

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

To wszystko, co musisz zrobić!


Czy można programowo utworzyć połączenie „wyjściowe” w kontrolerze widoku źródłowego?
Andrew Kirna

1

Swift 4.2, Xcode 10+

Dla tych, którzy zastanawiają się, jak to zrobić z VC nie skonfigurowanymi za pomocą scenorysu (ci, którzy przychodzą do tego pytania po wyszukiwaniu „programowo” + „odprężyć segue”).

Biorąc pod uwagę, że nie można programowo ustawić odwijania segue, najprostszym rozwiązaniem wyłącznie programowym jest wywołanie:

navigationController?.popToRootViewController(animated: true)

który wyskoczy wszystkie kontrolery widoku na stosie z powrotem do głównego kontrolera widoku.


Aby wyświetlić tylko najwyższy kontroler widoku ze stosu nawigacji, użyj:

navigationController?.popViewController(animated: true)


1
to zwykle więcej, niż chcesz - wystarczy cofnąć: [self.navigationController popViewControllerAnimated: YES];
Andy Weinstein

Rzeczywiście, dodałem to do mojej odpowiedzi - dzięki @AndyWeinstein
10623169

0

FYI: Aby odpowiedź @ Vadima działała z ręcznym działaniem odwijania seque wywoływanym z kontrolera widoku, musisz umieścić polecenie:

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

wewnątrz metody nadpisanej klasy viewDidAppear w następujący sposób:

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

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

Jeśli umieścisz go w innych metodach ViewController jak viewDidLoad lub viewWillAppear zostanie zignorowane.


3
Zdecydowanie źle. Wywołaj performSegueWithIdentifier z dowolnego miejsca.
smileBot

Czy nie wykonałoby to po prostu odejścia segregującego, gdy tylko załaduje się widok? Zamiast występować, kiedy chcesz, na przykład po naciśnięciu przycisku.
Pahnev,

@Pahnev tak to zrobi. Nie wiem, skąd ta odpowiedź ma jakieś pozytywne głosy. Wywołanie performSegueWithIdentfierrobi dokładnie to: wykonanie segue z jednego ViewController do drugiego
ezcoding 28.09.16

Całkowicie źle. Po uruchomieniu przewinąłby się natychmiast.
Lee Probert,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.