【问题标题】:Exception "Application tried to present modally an active controller" crash in iOS 8 only异常“应用程序试图以模态方式呈现活动控制器”仅在 iOS 8 中崩溃
【发布时间】:2015-02-24 22:42:37
【问题描述】:
UIPopoverController *popCtrl = [[UIPopoverController alloc] initWithContentViewController:self.rootViewController.navigationController];
popCtrl.delegate = self;
[popCtrl presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];

此代码在按钮操作中,其中按钮是“发送者”。

带有 presentPopoverFromBarButtonItem 的行导致抛出异常,原因是:Application tried to present modally an active controller DetailViewController: 0x15a54c00。在这种情况下,DetailViewController 是“self”,它只是 popCtrl 的一个委托,所以我看不出它是如何尝试以模态方式呈现的。它应该呈现 rootViewController.navigationController。

正如您可能从名称中猜到的那样,rootViewController 和 detailViewController 位于 SplitViewController 中,但在尝试使用弹出框呈现 rootViewController 之前,它已从 SplitViewController 中移除。

这只发生在使用 iOS 8 SDK 构建的 iOS 8 上。它也不是 100% 可重现的。大多数情况下会发生此异常,但有时在我重新启动应用程序后它根本不会发生,直到我重新运行应用程序,然后它又开始再次发生。 (我把它放在一个 try/catch 中,所以我知道它每次运行可能会发生多次。)

我几乎可以肯定这是 SDK 中的另一个 iOS 8 错误,但有人想出解决方法吗?

【问题讨论】:

  • 这个bug在iOS8.1中依然存在
  • 请参考此链接,希望对您有所帮助stackoverflow.com/questions/25094028/…
  • 感谢您的提示,但我认为这对我没有帮助,因为我没有使用故事板或 segues。

标签: ios uikit ios8


【解决方案1】:

我在更新一些应用程序时遇到了同样的问题,该应用程序最初是在 iOS 5.0 时代开发的。在弹出窗口中使用它之前从 UISplitViewController 中删除控制器不起作用,切换到更新的 UIPopoverPresentationController 也没有帮助。

但是,我能够从左侧滑入我的(主)控制器。或多或少,我偶然发现了这个“功能”,所以我查找了它的来源,并在 Apple 的 iOS SDK 5.1 发行说明中找到了它:

在 5.1 中,UISplitViewController 类在呈现左视图时采用了滑动呈现样式(以前只在 Mail 中看到)。当通过委托方法提供的现有条形按钮项或通过右视图中的滑动手势启动演示时,将使用此样式。无需额外的 API 采用即可获得此行为,所有现有 API,包括委托提供的 UIPopoverController 实例的 API,将继续像以前一样工作。如果您的应用程序不支持该手势,请将拆分视图控制器的 PresentWithGesture 属性设置为 NO 以禁用该手势。但是,不鼓励禁用手势,因为使用它可以在所有应用程序中保持一致的用户体验。

(来源:iOS 5.1 Release Notes,需要 Apple 开发者登录)

我没有测试如果您将提到的属性设置为 NO 并且如果它释放控制器会发生什么,但我不会对此抱太大希望。

因此,即使在从 UISplitViewController 手动删除它之后,我的视图控制器仍然在那个隐藏的可滑动窗格上处于活动状态,这似乎发生在 SDK 内部。我知道这在 iOS 7.x 之前仍然可以正常工作,但实际上我现在认为这是可以容忍的错误,并在 iOS 8.0 中关闭。

我最终完全放弃了弹出框并使用 iOS 5.1 及更高版本的默认 UISplitViewController 行为。对于一些额外的调整,您可以更改UISplitViewController.preferredDisplayMode 以满足您的需求,这为我节省了很多时间来升级从未听说过自动布局的旧代码。

【讨论】:

    【解决方案2】:

    我在 IBAction 中以编程方式使用 iOS 8 中的弹出框。我不知道这是否是一个错误,但我知道他们确实对模态视图和演示文稿进行了一些更改。上面有一个很好的 WWDC 视频,看看你能不能找到它。我这样做的方式(记住这是 Swift,所以你需要做一些翻译)如下:

    let controller = self.settingsVC
    controller.preferredContentSize = CGSizeMake(345, 234)
    controller.modalPresentationStyle = UIModalPresentationStyle.Popover
    var settingsPopController = controller.popoverPresentationController
    settingsPopController?.delegate = self
    settingsPopController?.sourceView = self.view
    settingsPopController?.sourceRect = sender.frame
    controller.modalPresentationStyle = UIModalPresentationStyle.Popover
    self.presentViewController(controller, animated: true, completion: nil)
    

    在这段代码中,self.settingsVC 是我设置的 ViewController 的一个属性,它被初始化为情节提要中的另一个 ViewController,但是您可以将控制器替换为您需要作为弹出框呈现的 ViewController。另外,请注意您的 UIViewController 类必须实现 UIPopoverPresentationControllerDelegate。 如果您在翻译方面需要任何帮助,我很乐意为您提供帮助。

    【讨论】:

    • 感谢您的建议,但使用 UIPopoverPresentationController 的新方法会导致完全相同的异常。
    猜你喜欢
    • 1970-01-01
    • 2013-01-06
    • 1970-01-01
    • 2020-06-06
    • 2011-12-25
    • 2014-03-03
    • 2013-02-15
    • 2023-01-25
    • 1970-01-01
    相关资源
    最近更新 更多