我正在尝试使用以下代码向UIViewController
中包含的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;
}];
}
但这是结果:
正如您所见,UINavigatioBar
和UIToolbar
仍在子视图控制器之上。如何将子视图控制器置于最重要的位置?我已经尝试用以下代码替换代码:
[self.navigationController addChildViewController:viewController];
[self.navigationController.view addSubview:viewController.view];
[viewController didMoveToParentViewController:self.navigationController];
但是这样viewDidAppear:animated
的{{1}}没有被调用,不知道为什么。
答案 0 :(得分:31)
@Sam的评论是正确的。您需要致电beginApperanceTransition:animated:
并endAppearanceTransition
来触发viewDidAppear
。添加子视图控制器时UINavigationController
不调用viewDidAppear
的原因是因为它已重写其容器组合方法以防止程序员在奇怪的位置添加子视图控制器。在您的情况下,它不希望您的子视图掩盖导航栏。导航控制器的正确用法是让孩子出现在导航栏下方。尽管如此,您仍然可以通过手动告知孩子何时出现以及何时完成显示来强制使用此非标准用户界面。
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];
}
];
答案 1 :(得分:7)
在第一个视图控制器中,执行以下操作:
- (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];
}
然后在第二个视图控制器中,为您的imageview添加getter:
-(UIImageView *)imageView
{
if( _imageView == nil )
{
_imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 548)];
[self.view addSubview:_imageView];
}
return _imageView;
}
答案 2 :(得分:0)
@Pwner回答Swift版本:
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()
})