web-dev-qa-db-fra.com

Ajouter un contrôleur de vue enfant à UINavigationController

J'essaie d'ajouter un contrôleur de vue enfant à une UIViewController contenue dans une UINavigationController avec ce code:

- (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;
    }];
}

Mais voici le résultat:

Image Result

Comme vous pouvez le voir, la UINavigatioBar et la UIToolbar sont toujours au-dessus du contrôleur de vue enfant. Comment puis-je placer le contrôleur de vue enfant au-dessus de tout? J'ai déjà essayé de remplacer le code avec:

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

Mais de cette façon, le viewDidAppear:animated de la viewController ne soit pas appelé, on ne sait pas pourquoi.

12
Fred Collins

Dans votre premier contrôleur de vue, faites quelque chose comme ceci:

- (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];
}

Ensuite, dans votre deuxième contrôleur de vue, ajoutez le getter pour votre imageview:

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

Le commentaire de @Sam est correct. Vous devez appeler beginApperanceTransition:animated: et endAppearanceTransition pour que viewDidAppear soit déclenché. La raison pour laquelle UINavigationController n'appelle pas viewDidAppear lorsque vous ajoutez un contrôleur de vue enfant est due au fait qu'il a remplacé ses méthodes de composition de conteneur afin d'empêcher le programmeur d'ajouter un contrôleur de vue enfant dans des endroits étranges. Dans votre cas, il ne veut pas que la vue de votre enfant recouvre la barre de navigation. L'utilisation correcte d'un contrôleur de navigation consiste à faire apparaître les enfants sous la barre de navigation. Néanmoins, vous pouvez toujours forcer cette interface utilisateur non standard en indiquant manuellement à l'enfant quand elle apparaît et quand elle a fini de s'afficher.

Ajouter un enfant à 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];
    }
];

Supprimer un enfant de 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];
    }
];
30
Pwner

@Pwner 's answer Version Swift:

Ajouter un enfant à UINavigaitonController

let child = MyChildViewController()
self.navigationController?.addChildViewController(child)
guard let navigationController = navigationController else {
    return
}
child.view.frame = navigationController.view.bounds
child.beginAppearanceTransition(true, animated: true)
self.navigationController?.view.addSubview(child.view)
self.view.alpha = 0
UIView.animate(withDuration: 0.3, animations: {
    child.view.alpha = 1.0
}, completion: { _ in
    guard let navigationController = self.navigationController else {
        return
    }
    child.endAppearanceTransition()
    child.didMove(toParentViewController: navigationController)
})

Supprimer un enfant de UINavigationController

child.willMove(toParentViewController: nil)
child.beginAppearanceTransition(false, animated: true)
UIView.animate(withDuration: 0.3, animations: {
    child.view.alpha = 0.0
}, completion: { _ in
    guard let navigationController = self.navigationController else {
        return
    }
    child.view.removeFromSuperview()
    child.endAppearanceTransition()
    child.removeFromParentViewController()
})
0
Ivan Smetanin