I\'m trying to add a child view controller to a UIViewController
contained in a UINavigationController
with this code:
- (void)buttonTa
@Pwner's answer Swift version:
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)
})
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()
})
@Sam's comment is correct. You need to call beginApperanceTransition:animated:
and endAppearanceTransition
for viewDidAppear
to be triggered. The reason why UINavigationController
does not call viewDidAppear
when you add a child view controller is because it has overridden its container composition methods to prevent the programmer from adding a child view controller in strange places. In your case, it doesn't want your child view to cover up the navigation bar. The correct usage of a navigation controller is to have children appear under the navigation bar. Nonetheless, you can still force upon this non-standard UI by manually telling the child when it is appearing and when it has finished appearing.
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];
}
];
[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];
}
];
In your first view controller, do something like this:
- (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];
}
Then in your second view controller, add the getter for your imageview:
-(UIImageView *)imageView
{
if( _imageView == nil )
{
_imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 548)];
[self.view addSubview:_imageView];
}
return _imageView;
}