ios - 对 <UIViewController : 0x176c0bd0> within a Navigation Controller 的开始/结束外观转换的不平衡调用

标签 ios uiviewcontroller uinavigationcontroller

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

Unbalanced calls to begin/end appearance transitions for UIViewController: 0x176c0bd0

帮助按钮连接到几乎是空的 ViewController - 退出按钮解除 segue

所有 Controller 都嵌入在导航 Controller 中。

我在这里阅读了很多人遇到同样问题的帖子,但是解决方案千差万别,我仍然没有找到正确的解决方案。我认为这是因为我从导航 Controller 中调用自定义 segue,但我的代码没有反射(reflect)这一点。我已经按照本教程创建了自定义转场 http://blog.dadabeatnik.com/2013/10/13/custom-segues/

初始 Controller 有以下方法:

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

    @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

知道为什么会出现这个错误吗?这是什么意思?以及如何解决?

最佳答案

我有同样的错误。该问题似乎与 removeFromSuperview 在与 presentViewController:animated:completion 相同的 viewController/view 的调用相同的运行循环中被调用这一事实有关。

要消除此警告,您可以做的一件事是在延迟后显示 View Controller :

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

但是,这种方法和带有警告的方法有时会出现闪烁,因为有一帧 View 已从父 View 中移除,但尚未呈现。

要解决此问题,您可以创建目标 View Controller 的快照 View ,并将其添加到 View 层次结构中以代替实际的 destinationViewController View ,然后在呈现 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];
    }];
}

关于ios - 对 <UIViewController : 0x176c0bd0> within a Navigation Controller 的开始/结束外观转换的不平衡调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26302511/

相关文章:

ios - 由于错误 "Failed to use existing instance 0 for app with bundle identifier: com.apple.Carousel",Apple Watch 应用无法构建

ios - CoreData - 在子上下文中管理文件引用

ios - 重置 UIButton 的框架中心点(具有布局约束)不起作用

ios - 在关闭中转到另一个 ViewController 不能快速工作

ios - Storyboard在不同时间显示多个 View

ios - 展开 Segue 不起作用 SWIFT

ios - 如何在 UINavigationController 的 View 下为 UIView 设置动画

ios - 通过 ViewControllers 传递数据 - 进行设置页面

ios - 如何在 Objective C 中将 NSArray 中的内容分成两个新的内容?

ios - 呈现 UINavigationController 并在导航栏上方显示附加(第二)标题