Mam teoretyczne pytanie. Teraz czytam przewodnik Apple ViewController .
Oni napisali:
Kiedy przychodzi czas na odrzucenie kontrolera widoku prezentowanego, preferowanym podejściem jest pozwolenie kontrolerowi widoku prezentacji na odrzucenie go. Innymi słowy, gdy tylko jest to możliwe, ten sam kontroler widoku, który przedstawił kontrolera widoku, powinien również wziąć odpowiedzialność za jego odwołanie. Chociaż istnieje kilka technik powiadamiania kontrolera widoku prezentującego, że jego kontroler widoku prezentowanego powinien zostać odrzucony, preferowaną techniką jest delegowanie.
Ale nie potrafię wyjaśnić, dlaczego muszę stworzyć protokół w przedstawionym VC i dodać zmienną delegata, stworzyć metodę delegata w prezentacji VC dla odrzucenia prezentowanego VC, zamiast prostego wywołania w przedstawionym widoku metoda kontrolera
[self dismissViewControllerAnimated:NO completion:nil]
?
Dlaczego pierwszy wybór jest lepszy? Dlaczego Apple to poleca?
źródło
presentingViewController
jest w większości bezużyteczne, ponieważ będzie odnosić się doUINavigationController
ifself
jest osadzone w jednym. W takim przypadku w ogóle nie będziesz w stanie uzyskaćpresentingViewController
. Jednak[self dismissViewControllerAnimated:completion]
nadal działa w tym przypadku. Moją sugestią byłoby dalsze używanie tego, dopóki Apple tego nie naprawi.Zaktualizowano dla Swift 3
Przyszedłem tutaj, chcąc odrzucić obecny (przedstawiony) kontroler widoku. Podaję tę odpowiedź każdemu, kto przyjeżdża tutaj w tym samym celu.
Kontroler nawigacji
Jeśli używasz kontrolera nawigacyjnego, jest to dość łatwe.
Wróć do poprzedniego kontrolera widoku:
Wróć do głównego kontrolera widoku:
(Dzięki tej odpowiedzi dla Objective-C.)
Kontroler widoku modalnego
Gdy kontroler widoku jest prezentowany modalnie, możesz go odrzucić (z drugiego kontrolera widoku), wywołując
Dokumentacja mówi,
Tak więc działa, aby kontroler widoku przedstawionego wywoływał go sam. Oto pełny przykład.
Delegaci
Pytanie PO dotyczyło złożoności wykorzystania delegatów do odrzucenia opinii.
Do tej pory nie potrzebowałem używać delegatów, ponieważ zwykle mam kontroler nawigacji lub kontrolery widoku modalnego, ale jeśli będę musiał używać wzorca delegata w przyszłości, dodam aktualizację.
źródło
Służy to do ponownego wykorzystania kontrolera widoku.
Twój kontroler widoku nie powinien przejmować się tym, czy jest prezentowany jako modalny, wypychany na kontrolerze nawigacji czy cokolwiek innego. Jeśli kontroler widoku sam się odrzuca, to zakładasz, że jest prezentowany modalnie. Nie będzie można wypchnąć tego kontrolera widoku na kontroler nawigacyjny.
Implementując protokół, pozwalasz nadrzędnemu kontrolerowi widoku zdecydować, w jaki sposób ma być prezentowany / wypychany i odrzucany / otwierany.
źródło
Spróbuj tego:
źródło
Z mojego doświadczenia wynika, że przydaje się, gdy trzeba usunąć go z dowolnego kontrolera ViewController i wykonać różne zadania dla każdego kontrolera widoku, który go odrzuca. Każdy kontroler viewController, który przyjmuje protokół, może odrzucić widok na swój własny sposób. (iPad vs iPhone lub przekazywanie różnych danych podczas zamykania z różnych widoków, wywoływanie różnych metod podczas zamykania itp.)
Edytować:
Tak więc, aby wyjaśnić, jeśli wszystko, co kiedykolwiek chcesz zrobić, to odrzucić widok, nie widzę potrzeby konfigurowania protokołu delegata. Jeśli musisz zrobić inne rzeczy po usunięciu go z różnych kontrolerów widoku prezentacji, najlepszym sposobem byłoby skorzystanie z delegata.
źródło
Cytuj z Przewodnika programowania kontrolerów firmy View , „Jak kontrolery przedstawiają inne kontrolery widoku”.
Z jednej strony zapewnia to ładną, wyważoną konstrukcję, dobre odsprzęganie itp. Ale z drugiej strony jest to bardzo praktyczne, ponieważ można szybko wrócić do określonego punktu w nawigacji.
Chociaż osobiście wolałbym raczej używać rozwijania segmentów niż próbować przechodzić wstecz przez drzewo kontrolerów widoku prezentacji , o czym Apple mówi w tym rozdziale, skąd pochodzi cytat.
źródło
Po pierwsze, jest to dobre podejście do kodowania. Spełnia wiele
OOP
zasad, np. SRP, Separacja problemów itp.Zatem kontroler widoku prezentujący widok powinien być tym, który go odrzuca.
Na przykład firma zajmująca się obrotem nieruchomościami, która daje dom do wynajęcia, powinna być upoważniona do jego zwrotu.
źródło
Swift 3.0 // Szybko zamknij kontroler widoku
źródło
Oprócz odpowiedzi Michaela Enriqueza przychodzi mi do głowy jeszcze jeden powód, dla którego może to być dobry sposób na ochronę przed nieokreślonym stanem:
Powiedz, że ViewControllerA przedstawia ViewControllerB modalnie. Ale ponieważ być może nie napisałeś kodu dla ViewControllerA, nie znasz cyklu życia ViewControllerA. Może odrzucić 5 sekund (powiedzmy) po zaprezentowaniu kontrolera widoku, ViewControllerB.
W tym przypadku, jeśli po prostu używasz
dismissViewController
ViewControllerB do odrzucenia samego siebie, skończyłbyś w niezdefiniowanym stanie - być może nie awarią lub czarnym ekranem, ale stan niezdefiniowany z twojego punktu widzenia.Gdybyś zamiast tego używał wzorca delegata, byłbyś świadomy stanu ViewControllerB i możesz zaprogramować przypadek taki jak ten, który opisałem.
źródło
Szybki
źródło
Jeśli używasz modalnego widoku, odrzuć.
źródło
To dużo bzdur. Delegacja jest w porządku, gdy jest potrzebna, ale jeśli sprawia, że kod jest bardziej złożony - a tak się dzieje - musi być ku temu powód.
Jestem pewien, że Apple ma swoje powody. Ale jaśniejsze i bardziej zwięzłe jest po prostu zlecenie przedstawionego VC odrzucenia, chyba że istnieje prawdziwy powód, by postąpić inaczej i nikt tutaj do dziś nie przedstawił takiego, który widzę.
Protokoły są doskonałe, gdy są potrzebne, ale w projektowaniu zorientowanym obiektowo nigdy nie chodziło o niepotrzebną komunikację modułów ze sobą.
Tom Love (współtwórca Objective C) powiedział kiedyś, że Objective C jest „elegancki”, „mały”, „ostry” i „dobrze zdefiniowany” (w porównaniu z C ++). Łatwo mu powiedzieć. Delegowanie to przydatna funkcja, która wydaje się być nadużywana „tylko dlatego”, i chociaż lubię pracować w języku, obawiam się, że będę zmuszony używać niepotrzebnej składni, aby uczynić rzeczy bardziej złożonymi, niż jest to konieczne.
źródło
Możesz zamknąć okno super widoku
self.view.superview?.window?.close()
źródło