iOS8 - 呈现模态视图会删除子视图

Posted

技术标签:

【中文标题】iOS8 - 呈现模态视图会删除子视图【英文标题】:iOS8 - Presenting a modal view removes sub view 【发布时间】:2014-09-16 15:05:00 【问题描述】:

我正在更新我们的应用程序以使用 xcode6/ios8 编译。

我遇到的一个问题是,当呈现模态视图时。底层子视图被移除。它完全变黑了..直到模态视图被关闭..然后它重新出现。

有没有人用 iOS8 遇到过这个问题?自 iOS4 以来,相同的代码一直有效。

代码:

    PigDetailViewController *pigDetailViewController = [[PigDetailViewController alloc] initWithNibName:@"PigDetailViewController" bundle:nil];

    self.navigationController.modalPresentationStyle = UIModalPresentationCurrentContext;
    self.navigationController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;


    [self presentViewController:pigDetailViewController animated:YES completion:nil];

【问题讨论】:

【参考方案1】:

在 iOS 8 中,他们添加了一种新的演示样式,在您描述的情况下,它的行为类似于 UIModalPresentationCurrentContext,它是 UIModalPresentationOverCurrentContext。这里的问题是,与 UIModalPresentationCurrentContext 不同,您希望将视图控制器设置为使用此演示样式呈现,如下所示:

PigDetailViewController *pigDetailViewController = [[PigDetailViewController alloc] initWithNibName:@"PigDetailViewController" bundle:nil];
pigDetailViewController.modalPresentationStyle = UIModalPresentationOverCurrentContext;
self.navigationController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentViewController:pigDetailViewController animated:YES completion:nil];

请注意,要支持 iOS 7 及更低版本,您可能需要检查操作系统版本并根据该版本决定如何呈现视图控制器。

编辑:我想再添加一个注释。在带有 UIModalPresentationCurrentContext 的 iOS7 中,当呈现的 VC 被关闭时,底层 VC 会调用其 viewDidAppear 方法。在带有 UIModalPresentationOverCurrentContext 的 iOS8 中,我发现底层 VC 没有调用其 viewDidAppear 方法,当其上方的 VC 被解除时。

【讨论】:

我同意罗杰的观点,这是正确答案,应该这样标记。 有什么想法可以调用底层的 vc viewDidAppear 吗?【参考方案2】:

在 BrennanR 的答案中添加一个点。即使 viewWillAppear 在其上方显示的 VC 被解除时也不会调用。

【讨论】:

【参考方案3】:

我认为您误解了模态视图控制器的工作原理。

当您以模态方式呈现视图控制器时,它将控制整个屏幕。它有一个不透明的背景(通常是黑色),然后在上面绘制它的视图。

因此,如果您将view.backgroundColor 设置为黄色(例如),它将具有黄色背景。如果您将其设置为清除,则它将显示为黑色背景。

我认为您想要的是让另一个视图“显示”,因此看起来模态视图位于其顶部。

我发现这样做的最好方法是使用这种方法...

// in the view controller that is presenting the modal VC
modalVC = // the modal VC that you will be presenting

UIView *snapshotView = [self.view snapshotViewAfterScreenUpdates:NO];
[modalVC.view insertSubView:snapshotView atIndex:0];

// present the modal VC

这将获取当前视图层次结构的“屏幕截图”,然后将该快照放置在模态 VC 中的所有内容之下。

这样你的黑屏就会被前一个视图控制器的截图代替。

【讨论】:

谢谢。我担心这已经运行了 2 年多了.. 只是在 iOS8 上才开始发生这种情况。我的模态视图比它弹出的底层视图小。在过去,底层视图仍然可见(在模态呈现视图的两侧)。 从 iOS 7 开始,您可以使用 UIModalPresentationCustom 和自定义的 transitioningDelegate 来将presentedViewController 插入为自定义模式...然后在 iOS 8 中,您可以更进一步并使用自定义UIPresentationController,让您更好地控制您还想展示的任何“辅助视图”(即调暗视图) @Fogmeister 我认为 mtg 的描述方式是正确的。我有同样的问题,并用 Reaveal 进行了检查。实际上,底层视图层次结构已被删除。 @brainray 这是正确的行为。他不正确的一点是这从未发生过。我认为从来没有这种情况。 此声明:“当您以模态方式呈现视图控制器时,它将控制整个屏幕。它具有不透明的背景(通常为黑色),然后在其上绘制视图。” 100% 错误。

以上是关于iOS8 - 呈现模态视图会删除子视图的主要内容,如果未能解决你的问题,请参考以下文章

删除子视图时如何修复触摸禁用?

ios 8 更改呈现/模态视图控制器的大小

从 SubView 呈现模态 ViewController

在 Ipad 上的模态视图上插入子视图

在 SwiftUI 中使用模态视图删除列表中的项目时崩溃

UIScrollView 删除子视图动画