Xcode iOS:popViewController出现意外行为

Xcode iOS:popViewController出现意外行为,xcode,ios,uinavigationcontroller,Xcode,Ios,Uinavigationcontroller,我一直在互联网上寻找解决方案。我什么也找不到。 因此: 我用的是UINavigationController。我正在推两个UIViewController到它上面。在第二个推送的ViewController中,我执行以下代码: - (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFailWithError:(NSError *)error { NSLog([error localizedDescription]); [self.nav

我一直在互联网上寻找解决方案。我什么也找不到。 因此: 我用的是UINavigationController。我正在推两个UIViewController到它上面。在第二个推送的ViewController中,我执行以下代码:

- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFailWithError:(NSError *)error {
NSLog([error localizedDescription]);
[self.navigationController popViewControllerAnimated:YES]; }
预期会发生的情况是,最后一个按下的ViewController将消失。在这个应用程序中,我在少数几个地方这样做,除了在这个ViewController中,它在任何地方都可以正常工作。 发生的情况是,只有后退按钮离开屏幕(动画),但其他所有东西都留在屏幕上。在控制台输出中,当这一行执行时,会打印出两个内容:

2011-03-14 16:32:44.580 应用程序[18518:207]嵌套的弹出窗口 动画可能会导致损坏 导航栏

2011-03-14 16:32:53.507 阿帕西[18518:207]完成了一个 意外情况下的导航转换 国家。导航栏子视图树 可能会被破坏

两条错误消息,我找不到任何相关信息。
我使用的是XCode 4和iOS SDK 4.3。也许任何人都可以帮我解决这个问题。

您可以在
viewdide出现之前的任何时间尝试弹出此对话框。如果您设置了一个标志,那么只需在
视图中选中该标志,您就不会有问题了。

我在代码中遇到了类似的情况,消息说:

嵌套推送动画可能导致导航栏损坏

正在以意外状态完成导航转换。导航栏子视图树>可能已损坏

我对这个问题的发现是,我在快速连续地一个接一个地推两个视图控制器,并且两个都设置了动画

在您的情况下,您可能会一个接一个地弹出带有动画的多个视图控制器

因此,当一个视图正在进行动画时,不应在另一个视图上启动动画

我还发现,如果在一个视图上禁用动画,错误消息就会消失

在我的例子中,这是流逻辑的问题,因为我不打算一个接一个地推两个视图控制器。一个在开关盒逻辑内被推,另一个在其结束后被推


希望这对某人有所帮助。

我也有这个问题,以下是导致我的问题的原因:

  • 在RootViewController中,我使用几个UISegmentedControl对象来确定下一步要加载的视图
  • 在那个(sub/2nd)视图中,我正在弹出(通过使用“后退”按钮)返回RootViewController
  • 在RootViewController中,我正在处理viewwillbeen,将我的每个UISegmentedControl对象“重置”为selectedSegmentIndex-1(表示没有段看起来“被按下”)
  • 该“重置”触发了我的每个UISegmentedControl对象,以触发其关联(和单独)iAction
  • 因为我没有处理-1的“选择”,所以我同时启动了多个方法,所有方法都试图推送不同的视图
  • 我的计划?我收紧了if…then语句,并在选择了segmentedindex=-1时停止执行UISegmentedControl iActions中的任何代码

    我仍然不知道为什么我会出现“弹出”动画错误,而不是“推送”错误,但至少我发现了我的错误并修复了它


    希望这对其他人有帮助

    我为UINavigationController创建了一个插入式替代品,它将为您的动画排队,并完全避免此问题


    抓取它是的,不幸的是苹果没有同步UINavigationController的动画。Andrew的解决方案非常优秀,但如果您不想涵盖其全部功能,有一个更简单的解决方案,覆盖这两种方法:

    // 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实例变量,就完成了。

    当我使用故事板时,这个问题会发生在我身上。我犯了一个错误: 我有一个UIButton,上面有一个操作要执行。因此,我将按钮与另一个ViewController链接,以便出现此问题

    要解决:
    链接UIButton中的按钮操作,并链接两个ViewController之间的按钮序列。

    结合MilGra和Andrew的回答,我得到了一种工作可靠、更简单的UINavigationController替代品

    这改进了MilGra的答案,使其能够与Push和pops一起工作,但比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
    

    我想是我自己弄明白的。我想这是因为我试图过早地弹出视图控制器。如果反向地理编码器提供了一个地址(在ViewDidLoad中启动)并失败,则视图尚未出现,因此动画弹出显然无法正常工作。我现在在ViewDidAppeare中实现了反向地理编码器的启动,一切似乎都很好。新手或多或少会犯错误。但我想知道的是,没有关于它的信息可以找到。最近,我遇到了同样的问题。原因是:-我试图两次错误地弹出视图控制器。您可以通过在push和pop View控制器上设置断点来检查此崩溃。他们在这里为我设置的键是:“…并且都是动画的。”谢谢!对于处理您希望这样做的情况,您有什么建议吗?例如,当我将视图控制器推到堆栈上,然后显示UIAlertView时,我经常看到这一点。我仍然想显示这两个视图,我只希望视图被推到堆栈上,然后警报视图出现,而无需实现一系列代理方法。感谢我将此设置更改为
    动画:YES
    设置为
    动画:NO
    ,并在
    视图上调用我的pop方法,解决了这个问题,这不是一个优雅的解决方案,但我在第二个操作上延迟了0.5秒,从而消除了这个错误,因为设置动画