在我看来,这些情况都是平行的:
我的 View Controller 显示了另一个全屏 View Controller ,现在已关闭
我的 View Controller 显示了另一个非全屏 View Controller ,现在已被关闭
我的 View Controller 显示了一个弹出窗口,现在已关闭
我的 View Controller 推送了另一个 View Controller ,现在已经弹出
在每种情况下,我的 View Controller 都不再是“最前面”的 View Controller ,然后再次成为“最前面”。我感到奇怪的是,iOS 没有向我的 View Controller 发送涵盖所有这些情况的单一“成为最前端”事件。
我认为我可以单独涵盖这些案例中的每一个,而且我认为这些都是我需要涵盖的所有案例,但生成的代码令人困惑且分散:
viewDidAppear
检测推送 View Controller 的弹出和全屏显示 View Controller 的关闭弹出框委托(delegate)消息检测弹出框的关闭
不确定是什么检测到非全屏呈现的 View Controller 的关闭
人们如何连贯而优雅地处理这个问题?
最佳答案
这些案例的共同点不是原始 View Controller 的出现,而是呈现/推送 View Controller 的消失。因此,一种简单明了的解决方案似乎是协议(protocol)和委托(delegate)架构。声明一对协议(protocol),如下:
protocol Home : class {
func comingHome()
}
protocol Away : class {
var home : Home? {get set}
}
extension Away where Self : UIViewController {
func notifyComingHome() {
if self.isBeingDismissed || self.isMovingFromParent {
self.home?.comingHome()
}
}
}
home view controller必须采用Home,并且在呈现或推送时必须将每个view controller的
home
设置为self
。呈现或推送的 View Controller 必须采用 Away,并且必须按如下方式实现
viewWillDisappear
:override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) self.notifyComingHome() }
这适用于问题中列出的四种情况。遗憾的是,Cocoa Touch 不会自动为您执行此操作。
编辑 由于 iOS 13 强制我们使用非全屏显示 View Controller ,这种方法在我的应用程序中变得更加重要。此外,我还对 UIAlertController 进行了子类化,以便它符合 Away。
关于ios - 统一UIViewController "became frontmost"检测?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54602662/