我一直在网上寻找解决方案。我找不到任何东西。 所以: 我正在使用UINavigationController。我正在推动两个UIViewControllers。在第二个推送的ViewController中,我正在执行此代码:
- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFailWithError:(NSError *)error {
NSLog([error localizedDescription]);
[self.navigationController popViewControllerAnimated:YES]; }
预期的事情将是最后推送的ViewController消失。在这个应用程序中,我在很少的地方这样做,它在这个非常ViewController期望到处都可以。 会发生什么是只有后退按钮离开屏幕(动画),但其他一切都停留在屏幕上。在控制台输出中,当执行此行时会打印出两个内容:
2011-03-14 16:32:44.580 TheAppXY [18518:207]嵌套pop 动画可能会导致损坏 导航栏
2011-03-14 16:32:53.507 TheAppXY [18518:207]完成了一个 意外的导航过渡 州。导航栏子视图树 可能会被破坏。
两条错误消息我找不到任何关于的信息。 我正在使用XCode 4和iOS SDK 4.3。也许任何人都可以帮我解决这个问题。
答案 0 :(得分:50)
我在我的代码中遇到了类似的情况,并且消息说:
嵌套推送动画可能导致导航栏损坏
在意外状态下完成导航转换。导航栏子视图树>可能会损坏。
我对这个问题的发现是我一个接一个地连续推动2个视图控制器,并且都是动画的。
在你的情况下,似乎你可能会一个接一个地弹出多个带有动画的视图控制器。
因此,当一个视图正在进行动画时,您不应该在另一个视图上开始动画。
我还发现,如果我在一个视图上禁用动画,则错误消息会消失。
在我的情况下,流逻辑存在问题,因为我不打算一个接一个地推送2个视图控制器。其中一个被推入开关盒逻辑,另一个被推到结束后。
希望这有助于某人。
答案 1 :(得分:28)
您可以在viewDidAppear
之前尝试弹出时随时获取此信息。如果您设置了一个标志,那么只需在viewDidAppear
中检查该标志,就不会有问题。
答案 2 :(得分:12)
我已经为UINavigationController创建了一个替代品,它会为你排队动画并完全避免这个问题。
抓取答案 3 :(得分:3)
我也有这个问题,这就是导致我的问题:
我的修复?当selectedSegmentIndex == -1时,我收紧了if ... then语句,并在我的UISegmentedControl IBActions中执行任何代码。
我仍然不确定为什么我会出现“pop”动画错误而不是“推”错误,但至少弄明白了我的错误并修复了它!
希望这有助于其他人!
答案 4 :(得分:0)
是的,不幸的是苹果没有同步UINavigationController的动画。安德鲁的解决方案非常出色,但如果您不想覆盖其整个功能,那么有一个更简单的解决方案,覆盖这两种方法:
// navigation end event
- ( void ) navigationController : ( UINavigationController* ) pNavigationController
didShowViewController : ( UIViewController* ) pController
animated : ( BOOL ) pAnimated
{
if ( [ waitingList count ] > 0 ) [ waitingList removeObjectAtIndex : 0 ];
if ( [ waitingList count ] > 0 ) [ super pushViewController : [ waitingList objectAtIndex : 0 ] animated : YES ];
}
- ( void ) pushViewController : ( UIViewController* ) pController
animated : ( BOOL ) pAnimated
{
[ waitingList addObject : pController ];
if ( [ waitingList count ] == 1 ) [ super pushViewController : [ waitingList objectAtIndex : 0 ] animated : YES ];
}
并创建一个名为waitingList的NSMutableArray实例变量,您就完成了。
答案 5 :(得分:0)
当我使用故事板时,这个问题发生在我身上。我犯了一个错误: 我有一个UIButton,有一个动作来执行SegueWithIdentifier。所以我将push segue与Button与另一个ViewController链接起来,所以出现了这个问题。
要解决: 链接UIButton中的按钮操作,并链接两个ViewControllers之间的push segue。
答案 6 :(得分:0)
结合MilGra和Andrew的答案给了我一些可靠的工作,并且是一个更简单的插入式UINavigationController替换。
这改善了MilGra的答案,使其适用于推送和弹出,但比Andrew的BufferedNavigationController更简单。 (使用BufferedNavigationController我偶尔会得到永远不会完成的转换,只会显示黑屏。)
在iOS8上似乎没有必要这样做,但在iOS7上仍然需要我。
@implementation UINavigationControllerWithQueue {
NSMutableArray *waitingList;
}
-(void) viewDidLoad {
[super viewDidLoad];
self.delegate = self; // NOTE: delegate must be self!
waitingList = [[NSMutableArray alloc] init];
}
# pragma mark - Overrides
-(void) pushViewController: (UIViewController*) controller
animated: (BOOL) animated {
[self queueTransition:^{ [super pushViewController:controller animated:animated]; }];
}
- (UIViewController *)popViewControllerAnimated:(BOOL)animated {
UIViewController *result = [self.viewControllers lastObject];
[self queueTransition:^{ [super popViewControllerAnimated:animated]; }];
return result;
}
- (NSArray*)popToRootViewControllerAnimated:(BOOL)animated {
NSArray* results = [self.viewControllers copy];
[self queueTransition:^{ [super popToRootViewControllerAnimated:animated]; }];
return results;
}
# pragma mark - UINavigationControllerDelegate
-(void) navigationController: (UINavigationController*) navigationController
didShowViewController: (UIViewController*) controller
animated: (BOOL) animated {
[self dequeTransition];
}
# pragma mark - Private Methods
-(void) queueTransition:(void (^)()) transition {
[waitingList addObject:transition];
if (waitingList.count == 1) {
transition();
}
}
-(void) dequeTransition {
if (waitingList.count > 0) {
[waitingList removeObjectAtIndex:0];
}
if (waitingList.count > 0) {
void (^transition)(void) = [waitingList objectAtIndex:0];
if (transition) {
transition();
}
}
}
@end