对<uiviewcontroller> </uiviewcontroller>的开始/结束外观转换的不平衡调用

时间:2014-03-27 02:07:45

标签: ios cocoa-touch uiviewcontroller

基于Apple documentation我提出了以下方法来在包容控制器​​中切换控制器。如果oldC我在控制台上收到Unbalanced calls to begin/end appearance transitions for <...>

- (void) showController:(UIViewController*)newC withView:(UIView*)contentView animated:(BOOL)animated
{
    UIViewController *oldC = self.childViewControllers.firstObject;
    if (oldC == newC) {
        return;
    }

    [oldC willMoveToParentViewController:nil];

    [self addChildViewController:newC];
    newC.view.frame = (CGRect){ 0, 0, contentView.frame.size };
    [contentView addSubview:newC.view];

    if (animated && oldC != nil) {
        oldC.view.alpha = 1.0f;
        newC.view.alpha = 0.0f;
        [self transitionFromViewController:oldC toViewController:newC duration:0.25f options:0 animations:^{

            oldC.view.alpha = 0.0f;
            newC.view.alpha = 1.0f;

         } completion:^(BOOL finished) {
            [oldC removeFromParentViewController];
            [newC didMoveToParentViewController:self];
         }];
    } else {
        oldC.view.alpha = 0.0f;
        newC.view.alpha = 1.0f;
        [oldC removeFromParentViewController];
        [newC didMoveToParentViewController:self];
    }
}

这就是我所说的:

- (IBAction) buttonSignIn:(id)sender
{
    [self showController:self.signInViewController withView:self.contentView animated:(sender != nil)];
}

- (IBAction) buttonSignUp:(id)sender
{
    [self showController:self.signUpViewController withView:self.contentView animated:(sender != nil)];
}

要跟踪此情况,我正在记录外观过渡

-(void)beginAppearanceTransition:(BOOL)isAppearing animated:(BOOL)animated
{
    [super beginAppearanceTransition:isAppearing animated:animated];
    NSLog(@"**begin %@", self);
}

-(void)endAppearanceTransition
{
    [super endAppearanceTransition];
    NSLog(@"**end** %@", self);
}

这就是日志的样子:

] **begin <SignInViewController: 0x10c769a20>
] **begin <SignUpViewController: 0x10c768770>
] Unbalanced calls to begin/end appearance transitions for <SignUpViewController: 0x10c768770>.
] **end** <SignUpViewController: 0x10c768770>
] **end** <SignInViewController: 0x10c769a20>

现在我有点困惑。这有什么问题?

3 个答案:

答案 0 :(得分:16)

结果transitionFromViewController:toViewController:duration:options:animations:completion:也会添加视图。

  

此方法将第二个视图控制器的视图添加到视图层次结构中,然后执行动画块中定义的动画。动画完成后,它将从视图层次结构中删除第一个视图控制器的视图。

这意味着addSubview需要相应调整。

- (void) showController:(UIViewController*)newC withView:(UIView*)contentView animated:(BOOL)animated
{
    UIViewController *oldC = self.childViewControllers.firstObject;
    if (oldC == newC) {
        return;
    }

    [oldC willMoveToParentViewController:nil];

    [self addChildViewController:newC];
    newC.view.frame = (CGRect){ 0, 0, contentView.frame.size };

    if (animated && oldC != nil) {
        oldC.view.alpha = 1.0f;
        newC.view.alpha = 0.0f;
        [self transitionFromViewController:oldC toViewController:newC duration:0.25f options:0 animations:^{

            oldC.view.alpha = 0.0f;
            newC.view.alpha = 1.0f;

         } completion:^(BOOL finished) {
            [oldC removeFromParentViewController];
            [newC didMoveToParentViewController:self];
         }];
    } else {
        [contentView addSubview:newC.view];
        oldC.view.alpha = 0.0f;
        newC.view.alpha = 1.0f;
        [oldC removeFromParentViewController];
        [newC didMoveToParentViewController:self];
    }
}

答案 1 :(得分:1)

旧代码

[self addChildViewController:toVC];
[fromVC willMoveToParentViewController:nil];
[self.view addSubview:toVC.view];
[toVC.view mas_makeConstraints:^(MASConstraintMaker *make) {
    make.edges.mas_equalTo(0);
 }];

 [self transitionFromViewController:fromVC
                      toViewController:toVC duration:0
                               options:UIViewAnimationOptionTransitionNone
                            animations:^{
                            } completion:^(BOOL finished) {
                                [fromVC.view removeFromSuperview];
                                [fromVC removeFromParentViewController];
                                [toVC didMoveToParentViewController:self];
                                self.currentVC = toVC;
                            }];

新代码,没关系

[self addChildViewController:toVC];
[fromVC willMoveToParentViewController:nil];

    [self transitionFromViewController:fromVC
                      toViewController:toVC duration:0
                               options:UIViewAnimationOptionTransitionNone
                            animations:^{
                            } completion:^(BOOL finished) {
                                [fromVC.view removeFromSuperview];
                                [fromVC removeFromParentViewController];
                                [toVC didMoveToParentViewController:self];
                                self.currentVC = toVC;
                            }];

答案 2 :(得分:0)

我将持续时间设置为0,这意味着animation:NO调用transitionFromViewController