Jaki jest proces urodzenia UIViewController (która metoda następuje po której)?
Istnieje wiele metod do nadpisania, takich jak initWithNibname:
, awakeFromNib
, loadView
, viewDidLoad
, viewDidAppear:
, layoutSubviews
, i po prostu nie mogę się zdecydować, w jakiej kolejności dostaje te metody nazywa.
7 answers
Wiele się dzieje za kulisami z Cocoa view i ViewController management .
1. Obiekt viewController
Najbardziej podstawowy, viewController jest ogólnym obiektem kontrolera. Gdy po raz pierwszy zostanie przydzielona inicjalizowana, nie ma z nią skojarzonego obiektu view. Widok jest tworzony tylko wtedy, gdy (i jeśli) jest wymagany. Tak więc, bez uwzględnienia widoku, cykl życia kontrolera viewController jest taki sam jak każdy inny obiekt:
UIViewController * myVC = [[UIViewController alloc] initWith...];
...
[myVC release];
Wyznaczonym inicjalizatorem dla kontrolerów viewcontrollerów jest -initWithNibname:bundle:
. Jeśli określisz nasadkę, viewController może automatycznie załadować swój widok z tej nasadki i podłączyć dowolne iboutlety, które zdefiniowałeś(więcej szczegółów znajdziesz poniżej).
2. Ładowanie i rozładowywanie widoku
ViewController załaduje swój widok zgodnie z wymaganiami. Zwykle dzieje się tak, gdy metoda -view
jest wywoływana po raz pierwszy i może się zdarzyć w dowolnym momencie w Twoim program, w zależności od sposobu inicjalizacji interfejsu użytkownika. Widok może również zostać zniszczony i przeładowany kilka razy w ciągu życia programu, w zależności od sposobu zarządzania interfejsem użytkownika. Gdy kontroler ViewController stwierdzi, że jego widok jest wymagany, ale nie jest jeszcze załadowany, zostanie wywołana metoda -loadView
. Podstawowy przepływ wiadomości przebiega w następujący sposób:
view
loadView
viewDidLoad
Zauważ, że jeśli nadpiszesz metodę -view
, -loadView
i viewDidLoad
nie zostaną wywołane automatycznie. Jeśli nadpisujesz -loadView
, musi ustawić właściwość viewController view
. W przeciwnym razie, następne wywołanie -view
ponownie uruchomi proces ładowania.
Widok może być również rozładowany w dowolnym momencie w trakcie życia programu, po prostu ustawiając właściwość view
na nil
. Domyślna implementacja -didReceiveMemoryWarning
zrobi to automatycznie, o ile widok nie ma superview (tzn. jeśli nie jest obecnie częścią aktywnego heirarchii widoku). Przepływ wiadomości przebiega następująco następuje:
view = nil
viewDidUnload
2a. ładowanie widoku programowo
Jeśli zdecydujesz się nadpisać -loadView
, możesz utworzyć widok, podwinięcia, inne kontrolery widoku i dowolne połączenia między tymi obiektami w dowolny sposób. Oczywiście oznacza to, że jesteś również odpowiedzialny za zarządzanie pamięcią w odniesieniu do obiektów, które tworzysz. Jeśli twoja podklasa nadpisuje -loadView
, powinna być zainicjalizowana za pomocą {[14] } zarówno dla nibName
, jak i bundle
.
2b. Ładowanie widok ze stalówki
Jeśli używasz pliku nib, Domyślna implementacja -loadView
automatycznie otworzy ten plik nib, utworzy instancje jego obiektów, doda połączenia między nimi i zajmie się zarządzaniem pamięcią.
Sprawy stają się nieco bardziej skomplikowane z plikami stali, ponieważ tak wiele dzieje się za kulisami. Metoda -awakeFromNib
jest wywoływana dla każdego obiektu , który jest tworzony podczas ładowania pliku nib i nie ma gwarancji, że drugi obiekty w pliku nib zostaną w pełni załadowane podczas jego wywoływania.
3. Wyświetlanie widoków
-viewWillAppear:
, -viewDidAppear:
, -viewWillDisappear:
i -viewDidDisappear:
są wywoływane tylko wtedy, gdy widok jest wyświetlany lub ukryty na ekranie, szczególnie podczas animowanych przejść z jednego widoku do drugiego. Metody te mogą być wywoływane wiele razy w ciągu życia programu, ponieważ widoki są zamieniane w schemacie nawigacji.
4. Zobacz układ
The -layoutSubviews
metoda jest nie częścią UIViewController
. Jest ona wywoływana dla UIView
obiektów, gdy ich granice zostały zmienione. Jeśli używasz niestandardowej podklasy UIView
w swoim programie, ta metoda może być używana do tworzenia niestandardowego układu podkategorii, zamiast polegać na domyślnych metodach automatyzacji Cocoa.
5. Składając wszystko razem
Ze względu na złożoność procesu istnieje wiele różnych sposobów, ale normalna oś czasu może wyglądać mniej więcej tak:]}-[viewController initWithNibname:Bundle:]
-[viewController awakeFromNib]
-[viewController loadView]
-[view awakeFromNib]
-[viewController viewDidLoad]
-[viewController viewWillAppear]
-[viewController viewDidAppear]
...
-[viewController viewWillDisappear] // user navigated away
-[viewController viewDidDisappear]
...
-[viewController viewWillAppear] // user navigated back
-[viewController viewDidAppear]
...
-[viewController viewWillDisappear] // user navigated away
-[viewController viewDidDisappear]
...
-[viewController setView:nil] // memory warning, perhaps
-[viewController viewDidUnload]
...
-[viewController loadView] // user navigated back
-[view awakeFromNib]
-[viewController viewDidLoad]
-[viewController viewWillAppear]
-[viewController viewDidAppear]
...
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-20 18:18:20
Przejrzałem to ostatnio i stworzyłem projekt testowy: https://github.com/Janek2004/ViewControllerTest
Uruchom projekt na symulatorze iOS, aby zobaczyć kolejność wykonywania metod podklasy UIViewController. Kolejność może być inna, gdy używamy pliku Nib zamiast storyboard lub load view controller programowo.
- -[ViewController initWithCoder:] Niearchive danych z nib lub storyboard
- -[ViewController awakeFromNib] przygotowuje odbiornik do obsługi po załadowaniu go z archiwum Interface Builder lub nib plik.
- -[ViewController loadView] nigdy nie należy wywoływać tej metody bezpośrednio. Kontroler widoku wywołuje tę metodę, gdy jego widok property is requested but is currently nil. Metoda ta ładuje lub tworzy widok i przypisuje go do właściwości view.
- -[ViewController viewDidLoad] metoda ta jest wywoływana po tym, jak kontroler widoku załadował swoją hierarchię widoków do pamięci.
- -[ViewController viewWillAppear:] metoda ta jest wywoływana przed dodaniem widoku odbiornika do hierarchii widoku i przed wszystkie animacje są skonfigurowane do wyświetlania widoku.
- -[ViewController viewWillLayoutSubviews] wywołane, aby powiadomić kontroler widoku, że jego Widok ma zamiar układać jego podview.Gdy a granice widoku zmieniają się, widok dostosowuje położenie jego podwidań. Kontroler widoku może zastąp tę metodę, aby wprowadzić zmiany przed widok przedstawia swoje podglądy.
- -[ViewController viewDidLayoutSubviews] wywołane, aby powiadomić kontroler widoku, że jego widok właśnie rozplanował swoje podwoje. Kiedy zmiana granic dla widoku kontrolera widoku, widok dostosowuje pozycji jego podwidywań, a następnie system wywołuje tę metodę. Jednak wywołanie tej metody nie wskazuje, że dostosowano poszczególne układy podwidań widoku. Każdy subview jest odpowiedzialny za dostosowanie własnego układu.
-[ViewController Viewdidappear:] powiadamia kontroler widoku, że jego Widok został dodany do hierarchii widoków. Możesz nadpisać tę metodę wykonywanie dodatkowych zadań związanych z prezentacją widoku.
-[ViewController Viewwilldisappear:] powiadamia kontroler widoku, że jego Widok ma zostać usunięty z hierarchii widoków.To metoda jest wywoływana w odpowiedzi na usunięcie widoku z widok hierarchia. Ta metoda jest wywoływana przed usunięciem widoku i zanim jakiekolwiek animacje zostaną skonfigurowane. Powiadamia widok kontrolera, że jego Widok został dodany do hierarchii widoków. Możesz zastąp tę metodę, aby wykonać dodatkowe zadania związane z przedstawiam widok.
- - [ViewController viewDidDisappear:] powiadamia kontroler widoku, że jego Widok został usunięty z hierarchii widoków.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-05 17:20:58
Innym kluczowym momentem w procesie jest wywołanie layoutSubviews na dowolnych podviewach. W tym momencie, a nie wcześniej, wszelkie ograniczenia skonfigurowane w storyboard zostały zastosowane. Jeśli chcesz wprowadzić zmiany w podwidywaniach widoku na podstawie jego ograniczonych współrzędnych, musisz to zrobić w layoutSubviews. Jeśli zrobisz to w viewDidLayoutSubviews, to będzie to za wcześnie, ponieważ te podview nie mają jeszcze zastosowanych ograniczeń (ponieważ jak mówi dokumentacja " każdy subview jest odpowiedzialny za dostosowanie własnego układu".) A jeśli zrobisz to w viewDidAppear, będzie to oczywiście za późno, ponieważ użytkownik zobaczy, że Twoje podviewy zmieniają współrzędne. Tak więc drugim ważnym krokiem w tym procesie jest:
-viewController viewWillAppear
-viewController viewWillLayoutSubviews
-viewController viewDidLayoutSubviews
---> viewController.[any subview] layoutSubviews
-viewController viewDidAppear
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-22 03:25:08
Z Dokumentacji Apple UIViewController:
Kiedy definiujesz nową podklasę UIViewController, musisz określić widoki, którymi kontroler będzie zarządzał. Istnieją dwa wzajemnie wykluczające się sposoby określenia tych widoków: ręcznie lub za pomocą pliku nib. Jeśli widoki zostaną określone ręcznie, należy zaimplementować metodę loadView i użyć jej do przypisania głównego obiektu widoku do właściwości view. Jeśli określisz widoki za pomocą pliku nib, nie możesz nadpisać loadView, ale zamiast tego należy utworzyć plik nib w Interface Builder, a następnie zainicjować obiekt kontrolera widoku za pomocą metody initwithnibname: bundle:. Tworzenie widoków za pomocą pliku nib jest często prostsze, ponieważ można użyć aplikacji Interface Builder do tworzenia i konfigurowania widoków graficznie(w przeciwieństwie do programowego). Obie techniki mają jednak ten sam efekt końcowy, który polega na stworzeniu odpowiedniego zestawu widoków i wyeksponowaniu ich za pomocą właściwości view.
Z top of my head:
- initWithNibname
- loadView (ładuj rzeczy ręcznie)
- viewDidiLoad
- viewDidAppear
Nie wiadomo gdzie wchodzi layoutSubviews
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-24 17:09:55
Generalnie rozwiązuję to pytanie, umieszczając NSLog (lub punkty przerwania) we wszystkich tych delegatach, w tym delegat uruchamiania aplikacji, i postępując zgodnie z kolejnością w debuggerze.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-24 16:46:53
-- This is related to view only: -viewWillAppear: -viewDidAppear: -viewWillDisappear: and -viewDidDisappear: are only called when the view is being displayed. -viewController viewDidLoad -viewController viewWillAppear -viewController viewDidAppear other methods -viewController viewDidDisappear -viewController viewWillDisappear -viewController viewDidUnload
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-21 08:56:59
Chcę podziękować E. James za jego doskonały opis. Nie mogę jeszcze skomentować posta, ale aby uzyskać szybką wizualną ilustrację, zapoznaj się z tym schematem przepływu w Przewodniku programowania kontrolera widoku. I zdaję sobie sprawę, że jest to off-topic, ale dla Wykres sekwencji uruchamiania aplikacji , zapoznaj się z przewodnikiem programowania aplikacji na iOS.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-03 22:00:46