ios - 统一UIViewController "became frontmost"检测?

标签 ios cocoa-touch uiviewcontroller

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

  • 我的 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/

相关文章:

ios - 通过 subview 移动一个正方形

ios - 即使在 GameScene 的 Update 方法中游戏还没有结束,我也会得到 "You Lose"

objective-c - 滚动表时向核心数据发出获取请求

iphone - UIView底部不显示

ios - 线程 1 EXC_bad_instruction (code=exc_1386_invop subcode=0x0)

swift - 在不使用 Storyboard的情况下更改 segue 动画?

ios - 将观察者代码从 ViewController 分离到不同的类

ios - 在 ViewController 和 TabBarController 之间传递数据

iphone - 为什么要在IOS中创建和使用Bundle?

iphone - 警告 : -Wuninitialized is not supported without -O