14

Ho un UIViewController che sto caricando da dentro un altro controller di visualizzazione e quindi aggiungendo la sua vista a UIScrollView.UIViewController viewWillAppear non chiamato quando si aggiunge come subView

self.statisticsController = [self.storyboard instantiateViewControllerWithIdentifier:@"StatisticsViewController"]; 
self.statisticsController.match = self.match; 

[self.scrollView addSubview:self.statisticsController.view]; 

ho messo i punti di interruzione nel controller visualizzare le statistiche e viewDidLoad viene chiamato ma viewWillAppear non lo è.

È perché non sto spingendolo nella gerarchia o qualcosa del genere?

+0

Sì, se una vista viene aggiunta come sottoview, viewDidAppear non verrà chiamato. È possibile aggirare il problema richiamandolo manualmente dalle viste principali viewDidAppear metodo – sbarow

+1

http: // stackoverflow.it/questions/5470552/viewdidappear-for-subviews – sbarow

+0

Ah, ho pensato che potesse essere il caso. Grazie. – Fogmeister

risposta

39

È necessario aggiungere statisticsController come controller di visualizzazione figlio del controller di cui si sta aggiungendo la vista.

self.statisticsController = [self.storyboard instantiateViewControllerWithIdentifier:@"StatisticsViewController"]; 
self.statisticsController.match = self.match; 

[self.scrollView addSubview:self.statisticsController.view]; 
[self addChildViewController:self.statisticsController]; 
[self.statisticsController didMoveToParentViewController:self]; 

Non sono sicuro che questo renderà viewDidAppear ottenere chiamato, ma è possibile ignorare didMoveToParentViewController: nel controller del bambino, e che saranno chiamati, in modo da poter mettere qualsiasi codice che si sarebbe messo in viewDidAppear in là .

+0

Questo attiverebbe i metodi viewDidAppear? – sbarow

+0

Ehi! Funziona così: D Grazie mille! @sarow si attiva il metodo viewWillAppear. – Fogmeister

+0

Ah è fantastico :-) – sbarow

10

Per impostazione predefinita, le richiamate di aspetto vengono automaticamente inoltrate ai bambini. È determinato con la proprietà shouldAutomaticallyFearwardMethods. Controllare il valore di questo propery, se è NO e se il bambino viewController dovrebbe apparirà sul l'aspetto del contenitore, si dovrebbe avvisare bambino con i seguenti metodi di attuazione di controllo del ciclo di vita del contenitore:

- (void)viewWillAppear:(BOOL)animated 
{ 
    for (UIViewController *child in self.childViewControllers) { 
     [child beginAppearanceTransition:YES animated:animated]; 
    } 
} 

- (void)viewDidAppear:(BOOL)animated 
{ 
    [self.child endAppearanceTransition]; 
} 

- (void)viewWillDisappear:(BOOL)animated 
{ 
    for (UIViewController *child in self.childViewControllers) { 
     [child beginAppearanceTransition:NO animated:animated]; 
    } 
} 

- (void)viewDidDisappear:(BOOL)animated 
{ 
    [self.child endAppearanceTransition]; 
} 

Customizing Appearance and Rotation Callback Behavior

fissato il mio problema! Spero che sarebbe utile.

+0

È lavoro per me ~ – 0xDatou

27

Ho riscontrato il problema -viewWillAppear: non chiamato di nuovo. Dopo aver cercato su Google, sono venuto qui. Ho fatto alcuni test e ho scoperto che l'ordine chiamante di -addSubview e -addChildViewController: è importante.

Caso 1. attiveranno -viewWillAppear: del controller, ma Caso 2, è WILL NOT chiamata -viewWillAppear:.

Caso 1:

controller?.willMoveToParentViewController(self) 

    // Call addSubview first 
    self.scrollView.addSubview(controller!.view) 
    self.addChildViewController(controller!) 

    controller!.didMoveToParentViewController(self) 

Caso 2:

controller?.willMoveToParentViewController(self) 

    // Call adChildViewController first  
    self.addChildViewController(controller!)  
    self.scrollView.addSubview(controller!.view) 

    controller!.didMoveToParentViewController(self) 
+4

Interessante. Ciò contraddice la documentazione di Apple nella guida alla programmazione del controller di visualizzazione. Dovresti presentare un bug. –

+0

Questo mi ha aiutato. –

+1

Qualche aggiornamento su questo? Sembra un insetto per me, ma sicuramente mi sono imbattuto nella stessa cosa. La documentazione di Apple afferma che il caso 2 è il modo corretto, e ha più senso (https://developer.apple.com/library/content/featuredarticles/ViewControllerPGforiPhoneOS/ImplementingaContainerViewController.html#//apple_ref/doc/uid/TP40007457-CH11 -SW13). Forse scriverò un radar ... – SeeMeCode

2

Per Apple (https://developer.apple.com/library/content/featuredarticles/ViewControllerPGforiPhoneOS/ImplementingaContainerViewController.html), il corretto ordine di chiamate API per aggiungere un controller di vista bambino è:

[self addChildViewController:childVC]; 
[self.view addSubview:childVC.view]; 
[childVC didMoveToParentViewController:self]; 

Ma ho ancora avuto il problema in cui viewWillAppear nel VC figlio non veniva chiamato in modo sporadico. Il mio problema era che c'era una condizione di competizione che poteva far sì che il codice sopra fosse eseguito prima che viewDidAppear fosse chiamato nel controller della vista del contenitore. Assicurare che viewDidAppear fosse già stato chiamato (o rimandare l'aggiunta del VC secondario fino a quando non lo fosse) lo ha risolto per me.

Problemi correlati