统一的UIViewController“成为最前端”检测?

时间:2019-02-09 02:42:24

标签: ios cocoa-touch uiviewcontroller

在我看来,这些情况都是平行的:

  • 我的视图控制器呈现了另一个全屏视图控制器,现在已被关闭

  • 我的视图控制器显示了另一个不全屏显示的视图控制器,现已被关闭

  • 我的视图控制器显示了一个弹出窗口,该弹出窗口现已被关闭

  • 我的视图控制器推送了另一个已弹出的视图控制器

在每种情况下,我的视图控制器都不再是“最前端”的视图控制器,然后又变为“最前端”。我很好奇iOS没有向我的视图控制器发送涵盖所有这些情况的单一毯子“成为最前面”事件。

我认为我可以单独覆盖所有这些情况,并且我认为这些都是我需要覆盖的所有情况,但是结果代码令人困惑且分散:

  • viewDidAppear检测到弹出式视图控制器的弹出和全屏显示视图控制器的关闭

  • 弹出窗口委托消息检测弹出窗口的关闭

  • 不确定是什么原因导致非全屏呈现视图控制器被解雇

人们如何连贯而优雅地处理这一问题?

2 个答案:

答案 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时,协调器可以调用该方法。