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

我有一个包含表视图的视图控制器,可以select表中的项目和正确创build一个细节视图控制器。

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

我有一个问题,当两个通知同时过期导致视图不能正确显示,另外还有控制台日志:“NNN是我的详细信息视图控制器NNN的开始/结束外观转换不平衡调用”。

表视图控制器创build如下:

self.tableViewController = [[TableViewController alloc] initWithNibName:@"TableView" bundle:nil]; UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:self.tableViewController]; self.window.rootViewController = navController; 

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

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

我读了一些地方,如果一个视图控制器推动另一个视图控制器时,它本身不在堆栈的顶部可能会有问题 – 所以我认为这一定是问题,因为当表视图控制器收到第二个通知它会不再位于导航堆栈的顶部,因为先前只有在第一个通知到达时才将详细视图控制器推入堆栈。

所以我将推送代码改为:

 [[self.navigationController topViewController].navigationController pushViewController:detailController animated:YES]; 

但是没有什么区别。

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

 [[NSNotificationCenter defaultCenter] postNotificationName: 

 [[NSNotificationQueue defaultQueue] enqueueNotification: postingStyle:NSPostWhenIdle] 

所以推送不会发生在应用程序循环的相同迭代中。 但是这没有什么区别,也没有试图推迟详细视图控制的推动:

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

我不知道问题是什么或接下来要做什么,有什么想法?

“开始/结束外观转换的不平衡呼叫”

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

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

这种导航会让用户感到困惑。 考虑让你的细节视图支持多个项目可能会更好。

“不平衡的呼叫开始/结束外观转换为'

说animation是在最后一个相关的animation没有完成之前开始的。 那么,在推新的视窗控制器之前,你是否会popup视窗控制器? 或者可能会跳到根? 如果是的话,请不要animation。 即

 [self.navigationController popToRootViewControllerAnimated:NO]; 

看看这是否解决了这个问题,在我的情况下,这个伎俩。

在当前视图控制器完成显示之前尝试并显示新的视图控制器时,会发生“不平衡的开始/结束外观转换的调用”错误。

所以,你必须确定在第一个animation完成之前你不会提供一个新的VC。

使用didShowViewController和willShowViewController来阻止在旧的完成其animation之前呈现一个新的VC。 这是为backButtonAction制作popViewController的animation: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]; } 

当您尝试从堆栈中不止一次popup一个VC时,也会发生这种情况。 就我的情况来说,popupVC的方法被错误地称为多次。 一旦我清理了这个问题就消失了。

其实你需要等到推动animation结束。 所以你可以委托UINavigationController,并防止推动,直到animation结束。

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

看看这些重载:

如果他们是空的,然后评论和重build。

 - (void) beginAppearanceTransition:(BOOL) isAppearing animated:(BOOL)animated {} - (void) becomeActive:(NSNotification *) notification {} 

您是否使用外观代理function?

我发现这个function很有问题,上次我有一个

“不平衡的呼叫开始/结束外观转换为”

我解决了它删除[[UITextField appearance] ..]方法。

希望这可以帮助