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

Posted

技术标签:

【中文标题】<UIViewController> 开始/结束外观转换的不平衡调用【英文标题】:Unbalanced calls to begin/end appearance transitions for <UIViewController> 【发布时间】:2014-03-27 02:07:45 【问题描述】:

基于Apple documentation,我想出了以下方法来在收容控制器中的控制器之间切换。当有oldC 时,我会在控制台上收到Unbalanced calls to begin/end appearance transitions for &lt;...&gt;

- (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>

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

【问题讨论】:

【参考方案1】:

原来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];
    

【讨论】:

我尝试了 tcurdt 建议的一切。经过几个小时的努力,我终于成功了。 tcurdt 你是天才! 如果您不想制作动画,可以安全地传递duration:0:developer.apple.com/library/ios/documentation/UIKit/Reference/…: 谢谢,你拯救了我的一天【参考方案2】:

旧代码

[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;
                            ];

【讨论】:

【参考方案3】:

我将持续时间设置为 0,这意味着 animation:NO 用于 transitionFromViewControllercall。

【讨论】:

以上是关于<UIViewController> 开始/结束外观转换的不平衡调用的主要内容,如果未能解决你的问题,请参考以下文章

从 UIVIewController 向 SKScene 传递数据

UI 多个视图控制器(UIViewController)间的 协议传值

带有 UIViewController(或 UITableViewController)的 tableView 属性

UIViewController所有API的学习。

UIViewController 类的未知类型名称

如何在 UIViewController 中更改 TableView 的属性