2012-03-16 8 views
32

Ustawienia: Mam zestaw scenorysów, z dwoma prostymi kontrolerami widoku A i B. Jest przycisk w A, który przechodzi do B z modalnym segue. B jest pokazane z przejściem modalnym na górze A. Jest w porządku.Jak odrzucić modal, który został zaprezentowany w UIStoryboard z modalnym segue?

Pytanie: czy istnieje sposób na oderwanie się od B i powrót do A za pomocą prostej magii?

Należy zauważyć, że jeśli to wszystko było w kontrolerze nawigacyjnym, a ja użyłem pchnięcia, to byłoby domyślnie zajęte przez kontroler nawigacyjny. Pojawi się przycisk "Wstecz". Nie ma nic porównywalnego z modalnościami, muszę zbudować interfejs, co jest w porządku, ale zastanawiam się, czy istnieje mechanika typu "segue", której mogę użyć, aby zasygnalizować powrót z B do A.

Teraz metoda oldskool do zbudowania wracając z b do a byłoby:

  • utworzyć właściwość delegata na b
  • zbiór a będzie delegatem b gdy modalne segue przejście odtwarza (mogę podpiąć do tego używając prepareForSegue: nadawca: w na kod)
  • kiedy nadszedł czas na odwołanie, B przekazuje swojemu delegatowi
  • A implementuje metodę delegowania, która odwołuje B

Działa, ale wydaje się zbyt duży i głupi.

Czy jest jakiś mechanik UIStoryboard, który przeoczyłem, to zasadniczo zrobiłoby "odwrotny modalny segue"?

Odpowiedz

44

Nie ma żadnej magii storyboardu dla odrzucenia kontrolera widoku modalnego bez napisania przynajmniej odrobiny kodu.

Ale kiedy trzeba zaimplementować własny kod, niekoniecznie musisz zadawać sobie tyle trudu. Możesz mieć tylko przycisk kontrolera widoku B, który wywołuje [self dismissViewControllerAnimated:YES completion:nil]. (Dokumenty mówią, że prezentujący kontroler widoku powinien być tym, który odrzuci, ale mówią też, że wiadomość zostanie przekazana do kontrolera przedstawiającego prezentację, jeśli zostanie wezwana do prezentacji.) Jeśli chcesz być bardziej konkretny - i ll muszą być w niektórych przypadkach, na przykład gdy jedna modalne widok kontroler jest przedstawiony z innym - można jawnie odwołać prezenterowi z self.presentingViewController i nazywają dismiss... stamtąd)

Widzisz działalności delegowanego w niektórych aplikacjach, ponieważ jest to jeden. sposób powiadamiania kontrolera podglądu A o tym, co zrobił użytkownik w trakcie kontrolowania kontrolera B ... ale nie jest to jedyny sposób. Jest KVO, powiadomienia lub zwykłe wywoływanie metod A po odwołaniu się do nich z self.presentingViewController (zakładając, że B wie, że zawsze jest prezentowany przez A). A jeśli A nie musi wiedzieć o tym, co wydarzyło się w B (powiedzmy, ponieważ użytkownik kliknął przycisk Anuluj), nie ma potrzeby robienia tego - możesz po prostu odrzucić modal i skończyć z nim.


W iOS 6, a później zrelaksować segues dodać inną opcję, zapewniając trochę ujęć „magii” na odwoływanie modalnych kontrolery widoku (lub inaczej „wycofania się” z sekwencji segues). Jednak takie podejście nadal wymaga podania kodu - nie można go ustawić w całości w scenopisie. Jednak na plusie ten kod zapewnia ścieżkę do uzyskania informacji od kontrolera widoku, który jest zwalniany (B) do tego, który go przedstawił (A).

Apple ma a tech note about unwind segues że pokrywa je w szczegółach, ale oto krótki wersję:

  1. zdefiniować IBAction metody w klasie widok kontrolera chcesz odpocząć do - ten, który prezentuje modalne kontroler widoku, a nie sam kontroler widoku modalnego (zobacz kontroler A w pytaniu). W przeciwieństwie do zwykłych metod IBAction, powinny one mieć parametr typu UIStoryboardSegue *; na przykład

    - (IBAction)unwindToMainMenu:(UIStoryboardSegue*)sender 
    
  2. W prezentowanym kontrolera widoku (nocleg w pytaniu), drut kontrola ikony zielonej Exit, a następnie wybierz metodę zdefiniowaną.

  3. W implementacji metody relaksu, można odwołać się do segue na sourceViewController do pobierania informacji z kontrolera widoku są oddalone. Nie musisz wywoływać numeru dismissViewControllerAnimated:completion:, ponieważ segue obsługuje usuwanie kontrolera widoku, który znika.

+0

Fajnie, nie wiedziałem o presentViewController (najwyraźniej nowy element iOS 5), który pomaga. – Jaanus

+2

Tak, jeśli chcesz zrobić to w niestandardowym segue dla łatwego ponownego użycia możesz zrobić coś w stylu - (void) wykonać { UIViewController * src = (UIViewController *) self.sourceViewController; [src.presentingViewController dismissModalViewControllerAnimated: YES]; } – AppHandwerker

+0

@SimonH Najlepsze porady dotyczące segues! –

30

Nie jest storyboard magia do osiągnięcia tego celu. Jest to tzw. Rela relaksacyjna. W pliku .h można zaimplementować dowolne metody stylu "docelowej akcji", które są potrzebne w przypadku wielu rozwijanych sekwencji, których potrzebujesz. Dla modalu jest to zwykle dwa (anuluj i zapisz). Więc w moim pliku Ah dodałbym:

// A.h file 
- (IBAction)myCancelUnwindSegueCallback:(UIStoryboardSegue *)segue; 
- (IBAction)mySaveUnwindSegueCallback:(UIStoryboardSegue *)segue; 

Teraz w serii ujęć, jeśli masz segue od A do B. Teraz można zrobić „akcja cel” przeciągnij sterowania styl od anulowania/przyciski oszczędzają w B do zielonej ikony "Exit" na dole kontrolera B w scenorysie. Gdy to zrobisz, Xcode pobierze dwie metody, które stworzyliśmy (ponieważ są one w pliku nagłówkowym A i mają poprawny podpis (np. IBAction i UIStoryboardSegue *.), A B jest celem podróży z A). tam to masz. Masz magię storyboardu, której szukałeś!

W realizacji dwóch wywołań zwrotnych, to masz coś takiego jak:

// A.m file 
- (IBAction)myCancelUnwindSegueCallback:(UIStoryboardSegue *)segue { 
    UIViewController *modalGoingAway = segue.sourceViewController; 
    // Do something (like get data) from modalGoingAway if you need to... 
} 

- (IBAction)mySaveUnwindSegueCallback:(UIStoryboardSegue *)segue { 
    UIViewController *modalGoingAway = segue.sourceViewController; 
    // Do something (like get data) from modalGoingAway if you need to... 
} 

Wreszcie, jeśli ta metoda spełnia Twoje potrzeby, to świetnie. Jesteś skończony. Nadal jednak podłączam cały schemat delegowania protokołu/źródła danych, jeśli "on cancel" lub "on save" Chcę wykonać pewne operacje na prywatnych właściwościach B przed przekazaniem kontroli do A, aby usunąć B z hierarchii widoku.

+1

uwaga 2 rzeczy: 1) w oddzwanianiu nie ma potrzeby odrzucania modalu, ponieważ zostanie on automatycznie odrzucony przez odroczenie ruchu (i spowoduje błąd, jeśli spróbujesz) 2) rozwiń działania segue (zielony przycisk wyjścia) działa z iOS6 cel. jest nieco mylące, ponieważ przy starszym celu zobaczysz zielony przycisk wyjścia, który nie ma znaczenia) –

+1

To nie jest naprawdę pełna "magia storyboardów", ponieważ wciąż musisz dodać kod do kontrolera widoku. Ale w moim przypadku B jest po prostu statyczną treścią, więc to bicie musi utworzyć podklasę kontrolera widoku B tylko po to, by ją odrzucić. – jab

Powiązane problemy