objective-c 将子视图控制器添加到 UINavigationController
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19257999/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Add child view controller to UINavigationController
提问by Fred Collins
I'm trying to add a child view controller to a UIViewControllercontained in a UINavigationControllerwith this code:
我正在尝试使用以下代码将子视图控制器添加到UIViewController包含在 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;
}];
}
But this is the result:
但这是结果:


As you can see the UINavigatioBarand the UIToolbarare still on top of the child view controller. How can I put the child view controller on top of all? I've already tried to replace the code with:
正如你所看到的,UINavigatioBar和UIToolbar仍然在子视图控制器的顶部。如何将子视图控制器放在最重要的位置?我已经尝试将代码替换为:
[self.navigationController addChildViewController:viewController];
[self.navigationController.view addSubview:viewController.view];
[viewController didMoveToParentViewController:self.navigationController];
But in this way the viewDidAppear:animatedof the viewControllerdoesn't get called, dunno why.
但是,在这种方式viewDidAppear:animated的viewController不会被调用,说不上为什么。
采纳答案by JonahGabriel
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:
然后在你的第二个视图控制器中,为你的图像视图添加 getter:
-(UIImageView *)imageView
{
if( _imageView == nil )
{
_imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 548)];
[self.view addSubview:_imageView];
}
return _imageView;
}
回答by Pwner
@Sam's comment is correct. You need to call beginApperanceTransition:animated:and endAppearanceTransitionfor viewDidAppearto be triggered. The reason why UINavigationControllerdoes not call viewDidAppearwhen 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.
@Sam的评论是正确的。你需要调用beginApperanceTransition:animated:,并endAppearanceTransition为viewDidAppear被触发。添加子视图控制器时之所以UINavigationController不调用viewDidAppear,是因为它已经覆盖了它的容器组合方法,以防止程序员在奇怪的地方添加子视图控制器。在您的情况下,它不希望您的子视图覆盖导航栏。导航控制器的正确用法是让孩子出现在导航栏下方。尽管如此,您仍然可以通过手动告诉孩子它何时出现和何时完成来强制使用此非标准 UI。
Add a child to UINavigationController
将子项添加到 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];
}
];
Remove a child from UINavigationController
从 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];
}
];
回答by Ivan Smetanin
@Pwner's answer Swift version:
@Pwner的回答 Swift 版本:
Add child to UINavigaitonController
将子项添加到 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)
})
Remove a child from UINavigationController
从 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()
})

