"推送多个详细视图控制器时,对DetailViewController的开始/结束外观转换的不平衡调用"

Gru*_*kes 62 ios

我有一个包含表视图的视图控制器,可以选择表中的项目和正确创建的详细视图控制器.

表中的项表示可以具有与其关联的基于时间的触发器的项目,并且为每个项目安排本地通知,如果当本地通知到期时应用程序在前台,则自动显示该项目的详细视图.

我有一个问题,当两个通知同时到期导致视图无法正常显示时,以及控制台日志:"NNN的开始/结束外观转换的不平衡调用",其中NNN是我的详细视图控制器.

表视图控制器创建如下:

 self.tableViewController = [[TableViewController alloc] initWithNibName:@"TableView" bundle:nil];
 UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:self.tableViewController];
 self.window.rootViewController = navController;
Run Code Online (Sandbox Code Playgroud)

当本地通知到期并且调用didReceiveLocalNotification:时,app会使用NSNotifcationCenter postNotificationName:来广播通知,并且表视图控制器正在侦听该通知.当表视图控制器收到该通知时,它会创建详细视图控制器并将其推送到堆栈,如下所示:

[self.navigationController pushViewController:detailViewController animated:YES]; 
Run Code Online (Sandbox Code Playgroud)

我在某处读到如果一个视图控制器在它本身不在堆栈顶部时推送另一个视图控制器可能会出现问题 - 所以我认为这一定是问题,因为当表视图控制器收到第二个通知时它会不再位于导航堆栈的顶部,因为它在以前只是在第一个通知到达时将详细视图控制器推送到堆栈上.

所以我将推送代码更改为:

[[self.navigationController topViewController].navigationController pushViewController:detailController animated:YES];
Run Code Online (Sandbox Code Playgroud)

但它没有任何区别.

所以我接下来认为可能会出现问题,因为第一个细节视图控制器没有机会在推送第二个视图控制器之前完全显示 - 所以我改变了我的应用程序的通知发布使用:

[[NSNotificationCenter defaultCenter] postNotificationName: 
Run Code Online (Sandbox Code Playgroud)

[[NSNotificationQueue defaultQueue] enqueueNotification: postingStyle:NSPostWhenIdle]
Run Code Online (Sandbox Code Playgroud)

因此推送不会发生在app循环的相同迭代中.但这没有任何区别,也没有试图推迟推送详细视图控件:

double delayInSeconds = 0.1;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
    [[self.navigationController topViewController].navigationController     pushViewController:detailController animated:YES]; 
});
Run Code Online (Sandbox Code Playgroud)

我不知道问题是什么或接下来要尝试什么,任何想法?

rai*_*ade 118

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

在当前视图控制器完成显示之前尝试显示新的viewcontroller时发生.您可以通过在viewWillAppear中导航来重现它.

基本上,您几乎在同一时间尝试将两个视图控制器推入堆栈.建议您在tableview控制器中维护一个队列,该队列维护一个需要显示的详细视图列表.一次按一个到堆栈并检查退出当前详细信息视图是否有任何需要显示的排队详细信息视图.

这种导航将使用户感到困惑.最好考虑使您的详细信息视图支持多个项目.

  • 关于此错误的其他答案中最有用的答案之一.请问你从哪里得到解释?当我调试时,我希望Apple文档出现在Google上,但我找不到任何关于此的文档. (2认同)

inf*_*oop 12

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

说动画是在最后一个相关动画没有完成之前开始的.那么,在推新视图控制器之前,你是否弹出任何视图控制器?或者可能会弹出根?如果是,请尝试不动画.即

[self.navigationController popToRootViewControllerAnimated:NO];
Run Code Online (Sandbox Code Playgroud)

看看这是否解决了这个问题,在我的情况下,这就解决了问题.


Gab*_*iel 7

当您在当前视图控制器完成显示之前尝试显示新的viewcontroller时,会出现"开始/结束外观转换的不平衡调用"错误.

因此,您必须确保在第一个完成动画之前不会出现新的VC.

使用didShowViewController和willShowViewController阻止在旧VC完成其动画之前呈现新VC.这是为backButtonAction创建一个带有Animation的popViewController:YES.

- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    [self.myNavView.backButton addTarget:self action:@selector(backButtonAction) forControlEvents:UIControlEventTouchUpInside];
}

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    [self.myNavView.backButton removeTarget:self action:@selector(backButtonAction) forControlEvents:UIControlEventTouchUpInside];
}
Run Code Online (Sandbox Code Playgroud)