2013-08-19 16 views
9

Zrobiłem prosty test, aby dowiedzieć się więcej na temat kontrolera widoku zamkniętego.
Mam kontroler widoku gdzie dodany/usunięty kontrolera widoku za pomocą dwóch przycisków Działanie:didMoveToParentViewController wywołany dwukrotnie


- (IBAction)myInfoAddAction:(id)sender { 
    profileViewController = [[ProfileViewController alloc] init]; 
    [self addChildViewController: profileViewController]; 
    UIView *__view = profileViewController.view; 
    [self.view addSubview: __view]; 
    [profileViewController didMoveToParentViewController: self]; 
} 

- (IBAction)myInfoRemoveAction:(id)sender { 
    [profileViewController willMoveToParentViewController: nil]; 
    [profileViewController.view removeFromSuperview]; 
    [profileViewController removeFromParentViewController]; 
} 

Klasa ProfileViewController rozciąga UIViewController i zastąpić willMoveToParentViewController i didMoveToParentViewController metody


-(void)willMoveToParentViewController:(UIViewController *)parent 
{ 
    [super willMoveToParentViewController: parent]; 
    NSLog(@"willMoveToParentViewController -> %@", self); 
} 

-(void) didMoveToParentViewController:(UIViewController *)parent 
{ 
    [super didMoveToParentViewController: parent]; 
    NSLog(@"didMoveToParentViewController -> %@", self); 
} 

-(void)viewWillAppear:(BOOL)animated 
{ 
    NSLog(@"viewWillAppear -> %@", self); 
} 

-(void)viewDidDisappear:(BOOL)animated 
{ 
    NSLog(@"viewDidDisappear -> %@", self); 
} 

Kiedy dodać widok kontrolera , Mam następujące dzienniki:


willMoveToParentViewController -> <ProfileViewController: 0x8c52ea0> 
viewWillAppear -> <ProfileViewController: 0x8c52ea0> 
didMoveToParentViewController -> <ProfileViewController: 0x8c52ea0> 
didMoveToParentViewController -> <ProfileViewController: 0x8c52ea0> 

Kiedy usunąć widok kontrolera:


willMoveToParentViewController -> <ProfileViewController: 0x8c52ea0> 
didMoveToParentViewController -> <ProfileViewController: 0x8c52ea0> 
viewDidDisappear -> <ProfileViewController: 0x8c52ea0> 
didMoveToParentViewController -> <ProfileViewController: 0x8c52ea0> 

Chciałbym wiedzieć, dlaczego didMoveToParentViewController wywoływana jest dwa razy?

Dzięki!

+0

Czy możesz również zalogować rodzica? Podejrzewam, że "nil" na jednym z tych przypadków wskazuje, że opuszczasz poprzedni kontroler. –

+0

To dość dziwne. Może powinieneś umieścić breakpoint w metodach i obserwować śledzenie stosu. Jednak myślę, że drugie wywołanie jest wyzwalane przez 'addSubview' i' removeFromSuperview'. – Sulthan

+0

Ostatnio wpadłem na ten sam problem. Wywołanie ** removeFromParentViewController ** przed ** removeFromSuperview ** prawdopodobnie naprawiło problem. To dziwne, ponieważ przykłady Apple konfigurują go tak, jak Ty. https://developer.apple.com/library/content/featuredarticles/ViewControllerPGforiPhoneOS/ImplementingaContainerViewController.html#//apple_ref/doc/uid/TP40007457-CH11-SW3 –

Odpowiedz

7

Miałem ten sam problem, jak również. Ponadto odkryłem, że po dodaniu kontrolera widoku podrzędnego podczas viewDidLoad, miałem tylko jedną wiadomość. Naprawiłem to, usuwając połączenie z numerem [super didMoveToParentViewController:]. Myślę, że problem związany jest z dodawaniem kontrolerów widoku podrzędnego podczas wywołania zwrotnego za pomocą przycisku, ale nie jestem pewien, dlaczego spowodowałoby to problem.

+2

To działa. Nie mogę sobie wyobrazić, że to poprawne rozwiązanie, ale myślę, że jesteś na czymś z dodawaniem kontrolerów widoku dziecka z wywołań zwrotnych. – user

0

Można odfiltrować powtarzające się wywołania systemowe didMoveToParentViewController, sprawdzając bieżący kontroler widoku rodzica. W takim przypadku możemy użyć super-połączenia, tak jak powinno być.

- (void)didMoveToParentViewController:(UIViewController *)parent { 
    [super didMoveToParentViewController:parent]; 

    if (parent == nil && self.parentViewController == nil) return; 
    if (parent != nil && self.parentViewController == parent) return; 

    // From here any code called once 
} 
Powiązane problemy