9

Sto cercando di aggiungere un controller di vista bambino ad un UIViewController contenuto in un UINavigationController con questo codice:Aggiungere View Controller bambino a UINavigationController

- (void)buttonTapped:(id)sender 
{ 
    MyChildController *viewController = [self.storyboard instantiateViewControllerWithIdentifier:@"MyChild"]; 
    [self addChildViewController:viewController]; 
    [self.view addSubview:viewController.view]; 
    [viewController didMoveToParentViewController:self]; 


    viewController.view.alpha = 0.0f; 
    [UIView animateWithDuration:0.4 animations:^{ 
     viewController.view.alpha = 1.0f; 
    }]; 
} 

Ma questo è il risultato:

Image Result

Come si può vedere lo UINavigatioBar e lo UIToolbar sono ancora in cima al controller di visualizzazione figlio. Come posso mettere il controller della vista bambino sopra tutto? Ho già provato a sostituire il codice con:

[self.navigationController addChildViewController:viewController]; 
    [self.navigationController.view addSubview:viewController.view]; 
    [viewController didMoveToParentViewController:self.navigationController]; 

Ma in questo modo il viewDidAppear:animated del viewController non viene chiamato, so perché.

risposta

5

Nel tuo primo controller della vista, fare qualcosa di simile:

- (IBAction)buttonClick:(id)sender 
{ 
    SecondViewController *secondView = [self.storyboard instantiateViewControllerWithIdentifier:@"SecondViewController"]; 
    UIImage *blurryImage = [UIImage imageNamed:@"foo.jpeg"]; 
    secondView.imageView.image = blurryImage; 
    [self.navigationController addChildViewController:secondView]; 
    secondView.view.frame = self.navigationController.view.frame; 
    [self.navigationController.view addSubview:secondView.view]; 
} 

Poi, nel tuo secondo controller della vista, aggiungere il getter per la vostra imageview:

-(UIImageView *)imageView 
{ 
    if(_imageView == nil) 
    { 
     _imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 548)]; 
     [self.view addSubview:_imageView]; 
    } 
    return _imageView; 
} 
+0

Sto cercando di utilizzare l'approccio viewcontroller-contenitore perché ho bisogno di offuscare la vista della vista modale sfondo controller che è anche semi-trasparente. L'effetto è lo stesso della vista di notifica che si tira giù dalla parte superiore dello schermo. Lo sfondo è semi-trasparente ed è anche sfocato/vetro smerigliato. Perché se aggiungo un controller vista figlio a 'self.navigationController' il metodo' viewDidAppear' non viene chiamato? –

+0

Hmm ... non è proprio sicuro ... hai provato a chiamare [viewController viewWillAppear: NO]? – JonahGabriel

+1

Sì e non fa nulla. Ho bisogno di chiamare '[viewController viewDidAppear: NO]' subito dopo la riga '[viewController didMoveToParentViewController: self.navigationController]'. Perché diavolo non si chiamano i metodi? Altrimenti se aggiungo il controller della vista figlio a 'self' e non a' self.navigationController' funziona, ma come mostrato nell'immagine sopra la vista è 'dentro' il 'navigationController'. –

28

s' @Sam commento è corretta. È necessario chiamare beginApperanceTransition:animated: e endAppearanceTransition per viewDidAppear da attivare. Il motivo per cui UINavigationController non chiama viewDidAppear quando si aggiunge un controller di visualizzazione figlio perché ha sovrascritto i suoi metodi di composizione contenitore per impedire al programmatore di aggiungere un controller di visualizzazione figlio in posizioni strane. Nel tuo caso, non vuole che la vista secondaria copra la barra di navigazione. L'uso corretto di un controller di navigazione è far apparire i bambini sotto la barra di navigazione. Tuttavia, è comunque possibile forzare questa UI non standard comunicando manualmente al bambino quando appare e quando è finita di apparire.

Aggiungi un bambino di UINavigationController

MyChildViewController* child = [[MyChildViewController alloc] init]; 
[self.navigationController addChildViewController:child]; 
child.view.frame = self.navigationController.view.bounds; 
[self.navigationController.view addSubview:child.view]; 
child.view.alpha = 0.0; 
[child beginAppearanceTransition:YES animated:YES]; 
[UIView 
    animateWithDuration:0.3 
    delay:0.0 
    options:UIViewAnimationOptionCurveEaseOut 
    animations:^(void){ 
     child.view.alpha = 1.0; 
    } 
    completion:^(BOOL finished) { 
     [child endAppearanceTransition]; 
     [child didMoveToParentViewController:self.navigationController]; 
    } 
]; 

Rimuovere un bambino da UINavigationController

[child willMoveToParentViewController:nil]; 
[child beginAppearanceTransition:NO animated:YES]; 
[UIView 
    animateWithDuration:0.3 
    delay:0.0 
    options:UIViewAnimationOptionCurveEaseOut 
    animations:^(void){ 
     child.view.alpha = 0.0; 
    } 
    completion:^(BOOL finished) { 
     [child endAppearanceTransition]; 
     [child.view removeFromSuperview]; 
     [child removeFromParentViewController]; 
    } 
]; 
+1

Penso che il bambino chiamerà 'didMoveToParentViewController:' quando viene rimosso .. Qualcosa di simile, '[child didMoveToParentViewController: nil]' –

+0

Mi ha aiutato ... grazie. Ha dato voti positivi a Pwner. – Femina

+0

molto utile, grazie! – kernix

Problemi correlati