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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了对开始/结束外观转换的不平衡调用相关的知识,希望对你有一定的参考价值。

我读到了关于遇到类似error的另一个用户的SO,但是这个错误是在不同的情况下。

我最初添加View Controller时收到此消息:

Unbalanced calls to begin/end appearance transitions for 
<UITabBarController: 0x197870>

该应用程序的结构如下:

我有一个5个标签的TabBarController链接到5个视图控制器。在初始显示选项卡中,我调出一个新的视图控制器来覆盖作为应用程序的介绍。

我使用此代码调用介绍视图控制器:

IntroVC *vc = [[IntroVC alloc] init];
[self presentModalViewController:vc animated:YES];
[vc release]; 

在此IntroVC视图控制器出现后,上面的错误显示。

附:我正在使用xCode 4.2和ios 5.0 SDK,开发iOS 4.3应用程序。

答案

没有看到更多的周围代码,我无法给出明确的答案,但我有两个理论。

  1. 你没有使用UIViewControllerdesignated initializer initWithNibName:bundle:。尝试使用它而不仅仅是init
  2. 此外,self可能是标签栏控制器的视图控制器之一。始终从最顶层的视图控制器提供视图控制器,这意味着在这种情况下要求标签栏控制器代表视图控制器显示重叠视图控制器。您仍然可以将任何回调代理保留在实际视图控制器中,但您必须将标签栏控制器存在并关闭。
另一答案

因为拼写错误我遇到了这个问题:

let vc = storyboard.instantiateViewControllerWithIdentifier("...")
vc.transitioningDelegate = self
vc.modalPresentationStyle = .Custom

代替

override func viewDidAppear(animated: Bool) {
    super.viewWillAppear(animated)

它在超级而不是“DisAppear”中称为“Will Appear”

另一答案

我有同样的错误。我有一个带有3个项目的标签栏,我无意识地尝试使用override func viewDidAppear(animated: Bool) { super.viewDidAppear(animated) 调用我的标签栏项目2中项目1的根视图控制器。

发生的事情是它调用视图控制器并在几秒钟后返回到项目2的根视图控制器并记录该错误。

显然,您无法将项目的根视图控制器调用到另一个项目。

所以而不是performSegueWithIdentifier

我用过performSegueWithIdentifier

希望这有助于某人。

另一答案

我有同样的问题,并认为我会发布以防其他人遇到类似的东西。

在我的情况下,我已经将一个长按手势识别器附加到我的UITableViewController。

[self.parentViewController.tabBarController setSelectedIndex:0];

在我的onLongPress选择器中,我启动了我的下一个视图控制器。

UILongPressGestureRecognizer *longPressGesture = [[[UILongPressGestureRecognizer alloc]
                                                   initWithTarget:self
                                                   action:@selector(onLongPress:)]
                                                  autorelease];
[longPressGesture setMinimumPressDuration:1];
[self.tableView addGestureRecognizer:longPressGesture];

在我的情况下,我收到了错误消息,因为长按识别器触发了多次,因此,我的“SomeViewController”被多次推入堆栈。

解决方案是添加一个布尔值来指示SomeViewController何时被推入堆栈。当调用我的UITableViewController的viewWillAppear方法时,我将布尔值设置回NO。

另一答案

我遇到了第三方代码的问题。有人忘了将viewWillAppear和viewWillDis的超级内部设置在自定义TabBarController类中。

- (IBAction)onLongPress:(id)sender {

    SomeViewController* page = [[SomeViewController alloc] initWithNibName:@"SomeViewController" bundle:nil];

    [self.navigationController pushViewController:page animated:YES];

    [page release];

}
另一答案

在Swift 2+对我来说是有效的:

我在故事板中有UITabBarViewController,我有像这样的selectedIndex属性:

- (void) viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; // code... } or - (void) viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; // code... }

但我删除它,并添加我的初始类的viewDidLoad方法,如下所示:

enter image description here

我希望我可以帮助别人。

另一答案

实际上你需要等到推动画结束。因此,您可以委派UINavigationController并阻止推送直到动画结束。

override func viewDidLoad() {
   super.viewDidLoad()
   self.tabBarController?.selectedIndex = 2
}
另一答案

正如@danh建议的那样,我的问题是我在- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated{ waitNavigation = NO; } -(void)showGScreen:(id)gvc{ if (!waitNavigation) { waitNavigation = YES; [_nav popToRootViewControllerAnimated:NO]; [_nav pushViewController:gvc animated:YES]; } } 准备好之前呈现模态vc。然而,在呈现视图控制器之前,我感到不舒服依赖于固定的延迟(从我的测试中,我需要在UITabBarController中使用0.05-0.1s延迟)。我的解决方案是添加一个在performSelector:withDelay:UITabBarController方法上调用的块:

PRTabBarController.h:

viewDidAppear:

PRTabBarController.m:

@interface PRTabBarController : UITabBarController

@property (nonatomic, copy) void (^viewDidAppearBlock)(BOOL animated);

@end

现在在#import "PRTabBarController.h" @implementation PRTabBarController - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; if (self.viewDidAppearBlock) { self.viewDidAppearBlock(animated); } } @end

application:didFinishLaunchingWithOptions:
另一答案

我发现,如果您使用的是故事板,则需要在viewDidAppear中放置呈现新视图控制器的代码。它还将摆脱“不鼓励在分离的视图控制器上呈现视图控制器”警告。

另一答案

你需要确保 - (void)beginAppearanceTransition:(BOOL)isAppearing animated:(BOOL)animated和 - (void)endAppearanceTransition是在类中一起创建的。

另一答案

我遇到过同样的问题。开发时我想绕过屏幕。我通过调用选择器方法在viewDidLoad中从一个视图控制器导航到另一个视图控制器。

问题是我们应该让ViewController在转换到另一个ViewController之前完成转换。

这解决了我的问题:延迟是必要的,以允许ViewControllers在转换到另一个之前完成转换。

PRTabBarController *tabBarController = [[PRTabBarController alloc] init];

// UIWindow initialization, etc.

__weak typeof(tabBarController) weakTabBarController = tabBarController;
tabBarController.viewDidAppearBlock = ^(BOOL animated) {
    MyViewController *viewController = [MyViewController new];
    viewController.modalPresentationStyle = UIModalPresentationOverFullScreen;
    UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:viewController];
    [weakTabBarController.tabBarController presentViewController:navigationController animated:NO completion:nil];
    weakTabBarController.viewDidAppearBlock = nil;
};
另一答案

我通过将动画从YES更改为NO来修复此错误。

从:

[tabBarController presentModalViewController:viewController animated:YES];

至:

[tabBarController presentModalViewController:viewController animated:NO];
另一答案

当我从根TVC导航到TVC A然后导航到TVC B时,我遇到了这个问题。点击TVC BI中的“加载”按钮后,想直接跳回根TVC(无需重新访问TVC A,为什么要这样做) 。我有:

self.perform(#selector(YOUR SELECTOR METHOD), with: self, afterDelay: 0.5)

...给出了错误“不平衡的呼叫开始/结束等”。以下修复了错误,但没有动画:

//Pop child from the nav controller
[self.navigationController popViewControllerAnimated:YES];
//Pop self to return to root
[self.navigationController popViewControllerAnimated:YES];

这是我的最终解决方案,没有错误,仍然是动画:

//Pop child from the nav controller
[self.navigationController popViewControllerAnimated:NO];
//Then pop self to return to root
[self.navigationController popViewControllerAnimated:NO];
另一答案

当我将UIButton连接到故事板segue动作(在IB中)时我遇到了这个错误,但后来决定让按钮以编程方式调用//Pop child from the nav controller [self.navigationController popViewControllerAnimated:NO]; //Then pop self to return to root, only works if first pop above is *not* animated [self.navigationController popViewControllerAnimated:YES]; 忘记从IB删除第一个。

本质上,它执行了两次segue调用,给出了这个错误并实际上将我的视图推了两次。解决方法是删除其中一个segue调用。

希望这能帮助像我这样累的人!

另一答案

danh发布

您可以通过在应用程序初始化之前显示模态vc来生成此警告。即启动一个选项卡式应用程序模板应用程序,并在self.tabBarController之上呈现一个模态vc作为application:didFinishLaunching中的最后一行。出现警告。解决方案:让堆栈首先展开,在另一个方法中显示模态vc,使用performSelector withDelay调用:0.0

尝试将方法移动到viewWillAppear并保护它,以便它只执行一次(建议设置属性)