68

我不断收到以下错误:

2011-04-02 14:55:23.350 AppName[42430:207] nested push animation can result in corrupted navigation bar
2011-04-02 14:55:23.352 AppName[42430:207] nested push animation can result in corrupted navigation bar
2011-04-02 14:55:23.729 AppName[42430:207] Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted.
2011-04-02 14:55:23.729 AppName[42430:207] Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted.

这就是我正在做的事情。从视图控制器中,当按下某个按钮时,我调用以下命令:

EventsViewController *viewController = [[EventsViewController alloc] init];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:viewController];
navController.navigationBar.tintColor = [UIColor blackColor];
[self presentModalViewController:navController animated:YES];
[viewController release];
[navController release];

然后,如果在 EventsController 中按下某个按钮,我会调用:

SingleEventViewController *viewController = [[SingleEventViewController alloc] initWithEvent:[currentEvents objectAtIndex:indexPath.row]];
[self.navigationController pushViewController:viewController animated:YES];
[viewController release];

然后,如果在 SingleEventViewController 中按下某个按钮,我会调用:

EventMapView* viewController = [[EventMapView alloc] initWithCoordinates];
[[self navigationController] pushViewController:viewController animated:YES];
[viewController release];

所以是的,很明显有嵌套的推送动画,但这不是正确的方法吗?我查看了 Apple 的 DrillDownSave 代码,这似乎是他们的做法。我使用 init 方法而不是 viewDidLoad 方法是否重要?

4

20 回答 20

119

pushViewController之前打电话viewDidAppear是不安全的。

于 2011-07-13T06:54:50.097 回答
92

两次意外触发相同的 SEGUE 一次在代码中,一次来自界面生成器,但两者同时...

我和你们其他人遇到了同样的错误。只有我的问题是我不小心两次触发了相同的segue。一次来自界面生成器,一次来自我的代码。

我有一个 UITableView。当一个单元格被选中时,界面生成器中的一个 segue 会触发。这是我的问题,我将segue设置为直接触发单击CELL ITSELf,在界面构建器内,然后在我的代码中,我在didSelectRowAtIndexPath下,代码会触发相同的segue......就像这样......

[self performSegueWithIdentifier:@"MySegue" sender:tableView];

这意味着当因为选择了一行而调用 didSelectRowAtIndexPath 时,它会使用上面的代码行触发 segue。然后界面构建器,也触发了segue,因为它直接连接到界面构建器中的单元格对象。阻止界面生成器直接触发 segue。您必须从视图控制器的顶部连接 segue,而不是嵌套在脱离单元本身的内部。

因此,如果您出于与我相同的原因遇到此问题,即您两次调用相同的 segue,您可以通过将连接从 CELL 直接取消链接到您的 segue 并让 segue 连接起源于IB 中表层次结构的顶部,而不是嵌套在单元格内。将视图控制器本身的 segue 连接到 segue。如果你做对了,当你选择 segue 时,它​​应该突出显示它来自的整个视图,而不仅仅是单元格。

现在 Apples 文档在 performSegueWithIdentifier:sender: 参考下声明:

应用程序通常不需要直接触发 segue。相反,您在 Interface Builder 中配置与视图控制器关联的对象,例如嵌入在其视图层次结构中的控件,以触发 segue。但是,您可以调用此方法以编程方式触发 segue,可能是为了响应无法在情节提要资源文件中指定的某些操作。例如,您可以从用于处理抖动或加速度计事件的自定义操作处理程序中调用它。

就我而言,我的 UITableView 有一个搜索按钮,并且必须确定当搜索结果表存在时是否调用 segue 或正常表视图存在。所以我需要直接触发segue。

因此,从界面构建器中删除嵌入式控件,并将其粘贴在视图控制器本身上,然后在您的代码中触发 segue!

现在,没有更多的双重segues!并且没有更多的错误。

希望有帮助,我花了好几个小时来解决这个问题。

于 2013-01-19T10:13:45.073 回答
13

我遇到了与您刚才相同的问题/错误消息,正在寻找解决方案并最终出现在此线程中,但是,对我来说,我发现该解决方案实际上只有一个动画:在进行嵌套推送时是放动画:是的,仅用于最后的推动),希望这会有所帮助

干杯。

于 2011-04-11T05:02:28.957 回答
9

我已经想通了。显然,如果您从 UITableViewDelegate 的 -didSelectRowAtIndexPath 方法之外调用 -pushViewController,它就不起作用。将调用移到该函数中有效。奇怪的。

于 2011-04-09T19:51:32.357 回答
8

我遇到了同样的问题,这是由于笔尖中的一个按钮连接到两个不同的操作而导致的。它尝试加载两个视图控制器,从而破坏堆栈。

于 2012-02-20T03:42:06.337 回答
4

当您说您使用 init 方法而不是 viewDidLoad 方法时,您是什么意思?

如果你在旧的推送没有被执行的机会之前推送一个新的视图控制器,你会得到这种错误。因此,将某些代码放入 init 并过早执行某些操作肯定会让您报告错误。

在视图控制器上运行 init 时,视图尚未加载!

于 2011-04-03T00:32:15.300 回答
2

嗯,我遇到了这个问题,而且我是整个 iOS 开发场景的新手。但是在界面构建器中查看我的连接检查器(带有文件所有者)后,我看到当我复制了一个按钮时,它具有分配给它的先前按钮方法以及我创建的新方法。我想这就是我的问题的嵌套方面的来源,因为它正在执行两种不同的方法,这两种方法都将视图推送到导航控制器上。我知道这已经得到了回答,但我想我会提出这个问题,以防万一其他人犯了像我这样的愚蠢错误。

于 2013-10-02T14:57:26.307 回答
1

这已经得到解答,但我认为这可能对其他人有所帮助,因为我遇到了同样的错误,但没有使用表视图。我终于弄清楚了问题所在。

我有一个现有的按钮,其 IBAction 调用了 pushViewController。我通过复制现有按钮创建了一个新按钮。新按钮还有一个调用 pushViewController 的操作。当点击新按钮(内部修饰)并按下视图控制器时,出现此错误。我删除了新按钮,从头开始创建它,将其绑定到现有的出口和操作,错误就消失了。

于 2012-07-17T00:21:41.963 回答
1

遇到同样的问题。就我而言,我错过了 switch 语句中的中断,因此同时触发了两个 segue。对我来说很容易解决。

于 2013-06-09T12:07:58.010 回答
1

我的问题与键盘处于活动状态有关。

这是通过从 textField 的委托方法推送 ViewController 引起的:

-(void)textFieldDidBeginEditing:(UITextField *)textField{

        FilterLocationViewController *destViewController = (FilterLocationViewController *)[self.storyboard instantiateViewControllerWithIdentifier:@"FilterLocationViewController"];

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

}

通过将代码更改为:

-(void)textFieldDidBeginEditing:(UITextField *)textField{

        [_textFieldLocation resignFirstResponder]; //adding this line

        FilterLocationViewController *destViewController = (FilterLocationViewController *)[self.storyboard instantiateViewControllerWithIdentifier:@"FilterLocationViewController"];

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

}

(添加行 [textField resignFirstResponder];)问题消失了。

基本上教训是,如果键盘不在,您不应该修改 navigationController 堆栈。

于 2014-04-02T02:49:17.510 回答
1

最近,我遇到了同样的问题。原因是:-我试图错误地弹出视图控制器两次。您可以通过在推送和弹出视图控制器上设置断点来检查此崩溃

于 2014-07-31T09:06:13.207 回答
0

1)也许您可以尝试在推送之前将必要的变量作为属性传递,UIViewController而不是使用带参数的 init 方法。无论如何,您很可能在 init 方法之外还需要这些参数。

此外,在您的initWithCoordinates:方法中,您缺少参数。可能您的自定义初始化方法是问题的一部分。

2) 就因为你提到viewDidLoad了——这个方法是在视图加载后进行初始化的。如果您在代码中创建 UIViewController,就像您所做的那样,您应该使用它loadView来设置您的子视图。

于 2011-04-03T01:55:01.030 回答
0

我的解决方案是

[self performSelector:@selector(moveTo) withObject:nil afterDelay:0.5];

于 2013-04-03T14:39:57.670 回答
0

这发生在我身上是因为我的UIControlEvents

    [button addTarget:self action:@selector(callSecondView) forControlEvents:UIControlEventAllTouchEvents];

如果由于 UIButton 调用而遇到问题,我必须将其更改UIControlEventAllTouchEventsUIControlEventTouchUpInside或者您希望您的按钮工作。

于 2013-07-11T18:32:23.267 回答
0

不知道别人的。我认为大多数使用 StoryBoard 的人都面临着这样的问题。我正在使用 XIB。

就我而言,问题是,当我使用推送移动到另一个视图时,我也在使用

 [self.navigationController popViewControllerAnimated:YES];

同时在当前View的ViewWillDisappear中。只需将其删除,它就可以正常工作。

由于需求和流程,我正在使用 POP。层次结构是 1 -> 2 ->3

我在视图 2 上并想移动到视图 3。在这种情况下,我遇到了这个错误。

于 2014-05-19T10:55:18.880 回答
0

就我而言,我既是从情节提要中设置推送转场,也是以编程方式设置。希望这会帮助任何人

于 2014-08-20T02:40:34.643 回答
0

我也收到了这个错误信息,导航栏和导航控制器的转换很奇怪。我的设置是嵌入在标签栏控制器中的一堆导航控制器。问题是我没有super.viewDidLoad()在我的标签栏控制器实现中调用viewDidLoad.

调用 super 是文档明确指出在覆盖 viewDidLoad 时应该做的事情,而我是通过艰难的方式学会了这一点。

也许这也可以帮助其他人!

于 2014-10-09T14:11:50.077 回答
0

我知道这已被回答,但它可以帮助其他人。

我遇到了同样的问题,但这是因为我对信息按钮使用了错误事件。我正在使用“UIControlEventAllTouchEvents”,这会在导航控制器中生成两个相同视图的推送。正确的事件是“UIControlEventTouchUpInside”。我是 iOS 新手。

于 2014-12-05T12:05:23.780 回答
-1

这解决了问题: https ://github.com/nexuspod/SafeTransition

如果您使用动画(动画:YES)推送(或弹出)视图控制器,它不会立即完成,如果您在动画完成之前再次推送或弹出,则会发生不好的事情。

要重现此错误,请尝试同时推送或弹出两个视图控制器。例子:

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    UIViewController *vc = [[UIViewController alloc] init];
    [self.navigationController pushViewController:vc animated:YES];
}

您将收到此错误:

2014-07-03 11:54:25.051 演示 [2840:60b] 嵌套推送动画可能导致导航栏损坏 2014-07-03 11:54:25.406 演示 [2840:60b] 在意外状态下完成导航转换. 导航栏子视图树可能会损坏。

只需将代码文件添加到您的项目中,并使您的导航控制器成为 APBaseNavigationController 的子类,就可以了。

于 2014-07-05T16:32:43.933 回答
-1

只是为了完成列表,这是另一个可能导致“嵌套推送动画可能导致导航栏损坏”的原因:

我确实在 TabBarController 中设置了几个 NavigationController,并在情节提要 Identify 属性中设置了 selectedIndex。将活动选项卡移动到代码后,错误消失了。

于 2016-04-29T19:00:17.283 回答