对导航控制器</uiviewcontroller中<uiviewcontroller:0x176c0bd0 =“”>的开始/结束外观转换的不平衡调用:>

时间:2014-10-10 15:07:38

标签: ios uiviewcontroller uinavigationcontroller

enter image description here我正在尝试编写自定义segue并遇到此错误

  

UIViewController的开始/结束外观转换的非平衡调用:0x176c0bd0

帮助按钮连接到几乎为空的ViewController - 退出按钮展开segue

所有控制器都嵌入在导航控制器中。

我在这里阅读了人们遇到同样问题的各种帖子,但解决方案变化很大,我仍然找不到合适的解决方案。我认为这是因为我在导航控制器中调用自定义segue,但我的代码没有反映出来。我已按照本教程创建自定义segue http://blog.dadabeatnik.com/2013/10/13/custom-segues/

初始控制器具有以下方法:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if([segue isKindOfClass:[ICIHelpSegue class]]) {
        ((ICIHelpSegue *)segue).originatingPoint = self.help.center;
    }      
}

- (IBAction)unwindFromViewController:(UIStoryboardSegue *)sender {
}

- (UIStoryboardSegue *)segueForUnwindingToViewController:(UIViewController *)toViewController fromViewController:(UIViewController *)fromViewController identifier:(NSString *)identifier {
     ICIUnwindHelpSegue *segue = [[ICIUnwindHelpSegue alloc] initWithIdentifier:identifier source:fromViewController destination:toViewController];
    segue.targetPoint = self.help.center;
    return segue;
}

ICIHelpSegue类是以下接口:

    @interface ICIHelpSegue : UIStoryboardSegue

     @property CGPoint originatingPoint;
     @property CGPoint targetPoint;

    @end

实现文件如下所示:

@implementation ICIHelpSegue
- (void)perform {
    UIViewController *sourceViewController = self.sourceViewController;
    UIViewController *destinationViewController = self.destinationViewController;
    UINavigationController *navigationController = sourceViewController.navigationController;

    [navigationController.view addSubview:destinatiionViewController.view]

    // Transformation start scale
    destinationViewController.view.transform = CGAffineTransformMakeScale(0.05, 0.05);

    // Store original centre point of the destination view
    CGPoint originalCenter = destinationViewController.view.center;
    // Set center to start point of the button
    destinationViewController.view.center = self.originatingPoint;

    [UIView animateWithDuration:0.5
                          delay:0.0
                        options:UIViewAnimationOptionCurveEaseInOut
                     animations:^{
                         // Grow!
                         destinationViewController.view.transform = CGAffineTransformMakeScale(1.0, 1.0);
                         destinationViewController.view.center = originalCenter;
                     }
                     completion:^(BOOL finished){
                         [destinationViewController.view removeFromSuperview]; // remove from temp super view
                         [navigationController presentViewController:destinationViewController animated:NO completion:NULL]; // present VC
                     }];
}

@end

发生此错误的任何想法?这是什么意思?以及如何解决?

1 个答案:

答案 0 :(得分:7)

我有同样的错误。这个问题似乎与removeFromSuperview在与调用presentViewController相同的运行循环中调用的事实有关:动画:完成同一个viewController / view。

要摆脱此警告,您可以做的一件事是在延迟后显示视图控制器:

    completion:^(BOOL finished)
    {
        destinationViewController.view removeFromSuperview];
        [navigationController performSelector:@selector(presentViewController:) withObject:destinationViewController afterDelay:0];
    }];

}

-(void)presentViewController:(UIViewController*)viewController
{
    [[self presentViewController:viewController animated:NO completion:nil];  
}

但是,此方法和带警告的方法有时会闪烁,因为有一个帧已从superview中删除了视图,但尚未显示。

要解决此问题,您可以创建目标视图控制器的快照视图,并将其添加到视图层次结构中以代替实际的destinationViewController视图,然后在显示destinationViewController之后将其删除:

    completion:^(BOOL finished)
    {
        UIView * screenshotView = [destinationViewController.view snapshotViewAfterScreenUpdates:NO];

        screenshotView.frame = destinationViewController.view.frame; 

        [destinationViewController.view.superview insertSubview:screenshotView aboveSubview: destinationViewController.view];
        [destinationViewController.view removeFromSuperview];

        [self performSelector:@selector(presentViewControllerRemoveView:) withObject:@[destinationViewController, screenshotView] afterDelay:0];


     }];
}

-(void)presentViewControllerRemoveView:(NSArray *)objects
{
    UIViewController * viewControllerToPresent = objects[0];
    UIView * viewToRemove = objects[1];

    [self presentViewController:viewControllerToPresent
                       animated:NO
                     completion:
    ^{
        [viewToRemove removeFromSuperview];
    }];
}