使用 Swift 4 关闭 iOS 中的所有模式

Posted

技术标签:

【中文标题】使用 Swift 4 关闭 iOS 中的所有模式【英文标题】:Dismiss all modals in iOS with Swift 4 【发布时间】:2018-11-15 13:21:59 【问题描述】:

我正在尝试实现类似于适用于 ios 的 Netflix 应用程序的导航。当您单击电影时,会弹出一个带有关闭按钮的模式窗口。如果在这部电影中我选择看另一部电影,则会弹出第二个模式,除了关闭按钮外,还会出现一个后退按钮。我可以使用后退按钮一一关闭,使用关闭按钮返回基本屏幕。

我可以使用

关闭单个视图
dismiss(animated: true, completion: nil)

但是我怎样才能返回到一次关闭所有模式的基本屏幕?另外,模态是要走的路吗?我选择这个是因为我不希望导航栏在顶部。

我正在使用 Xcode 10 中的 Swift 4.2。

【问题讨论】:

你可以通过创建协议来解除,但这将是一个漫长的过程 嗯,当您单击电影时出现的第一个视图控制器,源通过将其嵌入到 UINavigationController 中来呈现它。然后,当您单击另一部电影时,它是该导航控制器的push 转换。关闭按钮只使用您提到的默认dismiss(animated:completion) 为什么不让代表从 VC 中解散? 【参考方案1】:

您关闭 ViewController 的方式不是正确的方式。呈现视图控制器负责关闭视图控制器。理想情况下,您必须在呈现的 ViewController 中实现一个协议,并且从“呈现”的 ViewController 而不是“呈现”的 ViewController 中关闭模式。

您的方式仍然有效的原因是,当 ViewController 调用 self.dimiss 时,如果没有什么可以关闭 UIKit 会将其委托回其父级。如果你实现了这种正确的方式,一旦你 dismiss ,你呈现的 viewcontroller 将被解除,因此所有呈现的 viewcontroller 都将被解除,而不是最后一个。

From Apple Docs:

呈现视图控制器负责关闭它呈现的视图控制器。如果您在呈现的视图控制器本身上调用此方法,UIKit 会要求呈现的视图控制器处理解除。

如果您连续呈现多个视图控制器,从而构建一个呈现视图控制器的堆栈,则在堆栈中较低的视图控制器上调用此方法会关闭其直接子视图控制器以及堆栈上该子视图控制器上方的所有视图控制器。发生这种情况时,只有最顶层的视图会以动画方式消失;任何中间视图控制器都简单地从堆栈中删除。最顶层的视图使用其模态转换样式被解除,这可能与堆栈中其他视图控制器使用的样式不同。

如果要保留对视图控制器的呈现视图控制器的引用,请在调用此方法之前获取 presentViewController 属性中的值。

在显示的视图控制器上调用 viewDidDisappear(_:) 方法后调用完成处理程序。

【讨论】:

我可以使用destinationViewController.delegate = self 将一个委托从初始视图控制器(它实现要关闭的协议)设置为第一个模式。但是,当第一个模态调用第二个模态时会发生什么?如何告诉第二个模态其委托将是初始视图控制器而不是第一个模态? 您不必这样做。当初始 VC 关闭第一个模态时,所有用它启动的模态以及之后启动的任何子模态都将被关闭。 我不明白的是,如果我正在查看第二个模态并单击关闭按钮,如何从第二个模态调用初始 VC? @cesarcarlos 你只需要传递代表,例如:vc2.deleage = self.delegate 在你的vc1 中呈现vc2【参考方案2】:

试试这个

 self.navigationController?.viewControllers.removeAll(where: $0.isModalInPopover)

【讨论】:

以上是关于使用 Swift 4 关闭 iOS 中的所有模式的主要内容,如果未能解决你的问题,请参考以下文章

如何使用阿拉莫火? (设计模式)[关闭]

iOS Swift:闭包(回调)与委托,何时使用? [关闭]

Swift 中的可变参数方法

关闭 iOS 8 和 Swift 中的所有通知?

如何在 swift 中呈现自定义模式 [关闭]

Swift:防止 ABPeoplePickerNavigationController 关闭