将子视图控制器添加到UINavigationController

Fre*_*ins 15 iphone objective-c uiviewcontroller childviewcontroller ios7

我正在尝试使用此代码将子视图控制器添加到a中的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;
    }];
}
Run Code Online (Sandbox Code Playgroud)

但这是结果:

图像结果

正如您所看到的那样UINavigatioBar,UIToolbar它们仍位于子视图控制器的顶部.如何将子视图控制器置于最重要的位置?我已经尝试用以下代码替换代码:

[self.navigationController addChildViewController:viewController];
    [self.navigationController.view addSubview:viewController.view];
    [viewController didMoveToParentViewController:self.navigationController];
Run Code Online (Sandbox Code Playgroud)

但是,在这种方式viewDidAppear:animatedviewController不会被调用,不知道为什么.

Pwn*_*ner 32

@Sam的评论是正确的.你需要调用beginApperanceTransition:animated:,并endAppearanceTransitionviewDidAppear被触发.添加子视图控制器时UINavigationController不调用的原因viewDidAppear是它已重写其容器组合方法以防止程序员在奇怪的位置添加子视图控制器.在您的情况下,它不希望您的子视图掩盖导航栏.导航控制器的正确用法是让孩子出现在导航栏下方.尽管如此,您仍然可以通过手动告知孩子何时出现以及何时完成显示来强制使用此非标准UI.

将子项添加到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];
    }
];
Run Code Online (Sandbox Code Playgroud)

从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];
    }
];
Run Code Online (Sandbox Code Playgroud)

  • `beginAppearanceTransition`应该在`addSubview`之前调用,`endAppearanceTransition`应该在`removeFromSuperview`之后调用,否则可能会出现'unbalanced calls'错误. (2认同)

Jon*_*iel 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];
}
Run Code Online (Sandbox Code Playgroud)

然后在第二个视图控制器中,为imageview添加getter:

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

  • 为了调用`viewWillAppear:`和`viewDidAppear:`,你需要将消息`-beginAppearanceTransition:animated:`发送给负责你添加的视图的视图控制器.然后你做动画,如果有的话.在动画完成块中,将`-endAppearanceTransition`发送到出现的视图控制器.注意:不要调用`[viewController viewDidAppear:NO]` - 你永远不应该自己调用这些方法. (4认同)