在我看来,这些情况都是平行的:
我的视图控制器呈现了另一个全屏视图控制器,现在已被关闭
我的视图控制器显示了另一个不全屏显示的视图控制器,现已被关闭
我的视图控制器显示了一个弹出窗口,该弹出窗口现已被关闭
我的视图控制器推送了另一个已弹出的视图控制器
在每种情况下,我的视图控制器都不再是“最前端”的视图控制器,然后又变为“最前端”。我很好奇iOS没有向我的视图控制器发送涵盖所有这些情况的单一毯子“成为最前面”事件。
我认为我可以单独覆盖所有这些情况,并且我认为这些都是我需要覆盖的所有情况,但是结果代码令人困惑且分散:
viewDidAppear
检测到弹出式视图控制器的弹出和全屏显示视图控制器的关闭
弹出窗口委托消息检测弹出窗口的关闭
不确定是什么原因导致非全屏呈现视图控制器被解雇
人们如何连贯而优雅地处理这一问题?
答案 0 :(得分:0)
这些案例的共同点不是原始视图控制器的外观而是呈现/推动的视图控制器的消失。因此,一种简单明了的解决方案似乎是协议和委托体系结构。声明一对协议,如下所示:
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视图控制器必须采用Home,并且必须在每个视图控制器出现或推送时将其home
设置为self
。
显示或推送的视图控制器必须采用Away,并且必须实现viewWillDisappear
,如下所示:
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
self.notifyComingHome()
}
这适用于问题中列出的四种情况。可惜的是Cocoa Touch不能自动为您完成此操作。
答案 1 :(得分:0)
一种解决方案可能是采用MVVM-C风格体系结构中的协调器方法。您从不直接在VC中更改视图层次结构,而总是调用协调器为您完成此操作。 coordinator.showDetails(...)
此外,您在VC中定义了一个viewDidBecomeForemost
方法,当返回VC时,协调器可以调用该方法。