Po raz pierwszy zanurzam się w programowaniu na iOS i jedną z pierwszych rzeczy, które musiałem zrobić, jest zaimplementowanie niestandardowego kontrolera widoku kontenera - nazwijmy to SideBarViewController
- który zamienia, który z kilku możliwych kontrolerów widoku podrzędnego to pokazuje, prawie dokładnie jak standardowy kontroler paska zakładek . (To prawie kontroler paska kart, ale z ukrytym menu bocznym zamiast paska kart.)
Zgodnie z instrukcjami w dokumentacji Apple dzwonię addChildViewController
za każdym razem, gdy dodam element podrzędny ViewController do mojego kontenera. Mój kod do zamiany bieżącego kontrolera widoku podrzędnego, który SideBarViewController
wygląda następująco:
- (void)showViewController:(UIViewController *)newViewController {
UIViewController* oldViewController = [self.childViewControllers
objectAtIndex:0];
[oldViewController removeFromParentViewController];
[oldViewController.view removeFromSuperview];
newViewController.view.frame = CGRectMake(
0, 0, self.view.frame.size.width, self.view.frame.size.height
);
[self addChildViewController: newViewController];
[self.view addSubview: newViewController.view];
}
Potem zacząłem się zastanawiać, co addChildViewController
tu robi, i zdałem sobie sprawę, że nie mam pojęcia. Oprócz umieszczania nowego ViewController
w .childViewControllers
tablicy, wydaje się, że nie ma to żadnego wpływu. Działania i wyjścia z widoku kontrolera podrzędnego do kontrolera podrzędnego, które ustawiłem w scenorysie, nadal działają dobrze, nawet jeśli nigdy nie dzwonię addChildViewController
, i nie mogę sobie wyobrazić, na co jeszcze może to wpłynąć.
Rzeczywiście, jeśli przepiszę swój kod, aby nie wywoływał addChildViewController
, a zamiast tego wyglądał tak ...
- (void)showViewController:(UIViewController *)newViewController {
// Get the current child from a member variable of `SideBarViewController`
UIViewController* oldViewController = currentChildViewController;
[oldViewController.view removeFromSuperview];
newViewController.view.frame = CGRectMake(
0, 0, self.view.frame.size.width, self.view.frame.size.height
);
[self.view addSubview: newViewController.view];
currentChildViewController = newViewController;
}
... moja aplikacja nadal działa doskonale, o ile wiem!
Dokumentacja Apple nie rzuca zbyt wiele światła na to addChildViewController
, co robi, ani dlaczego powinniśmy to nazywać. Cały zakres stosownego opisu tego, co robi ta metoda lub dlaczego powinna być stosowana w jej sekcji w opisie UIViewController
klasy, jest obecnie:
Dodaje podany kontroler widoku jako element podrzędny. ... Ta metoda jest przeznaczona do wywołania tylko przez implementację niestandardowego kontrolera widoku kontenera. Jeśli zmienisz tę metodę, musisz wywołać super w swojej implementacji.
Jest też ten akapit wcześniej na tej samej stronie:
Kontroler widoku kontenera musi skojarzyć kontroler widoku podrzędnego ze sobą przed dodaniem widoku głównego elementu podrzędnego do hierarchii widoków. Dzięki temu system iOS może prawidłowo kierować zdarzenia do kontrolerów widoku podrzędnego i widoków, którymi zarządzają. Podobnie, po usunięciu głównego widoku podrzędnego z hierarchii widoków, powinien odłączyć ten podrzędny kontroler widoku od siebie. Aby utworzyć lub przerwać te skojarzenia, kontener wywołuje określone metody zdefiniowane przez klasę bazową. Te metody nie są przeznaczone do wywoływania przez klientów klasy kontenera; mają być używane tylko przez implementację twojego kontenera, aby zapewnić oczekiwane zachowanie powstrzymujące.
Oto podstawowe metody, z których możesz skorzystać:
addChildViewController:
removeFromParentViewController
willMoveToParentViewController:
didMoveToParentViewController:
ale nie daje żadnej wskazówki co do tego, jakie są „zdarzenia” lub „oczekiwane zachowanie powstrzymujące”, o którym mowa, ani dlaczego (lub nawet kiedy) wywołanie tych metod jest „niezbędne”.
Wszystkie przykłady niestandardowych kontrolerów widoku kontenera w sekcji „Niestandardowe kontrolery widoku kontenera” w dokumentacji Apple wywołują tę metodę, więc zakładam, że służy ona do jakiegoś ważnego celu poza zwykłym umieszczeniem elementu podrzędnego ViewController na tablicy, ale nie mogę zrozumieć co to jest za cel. Co robi ta metoda i dlaczego mam ją nazywać?