为什么viewWillAppear没有被调用?
您为什么期望如此?
最有可能的是-您想知道您的用户将要看到一个屏幕。
有各种各样有用的理由想要这个。 也许您想跟踪分析屏幕视图,或触发数据获取以保持屏幕新鲜。 无论您的目标是什么,有人都可能告诉您检查viewWillAppear
-好消息。 它会实现这些目标,但有时会起作用。 *
简单答案
调用viewWillAppear
的技术原因很简单。
通知视图控制器其视图将被添加到视图层次结构中。
它不能是任何视图层次结构-它必须是在根目录下具有UIWindow
视图层次结构(不一定是可见窗口)。
如果您从一个选项卡跳到另一个选项卡,或者从UINavigationController
推送并弹出,那很好。 iOS正在从视图层次结构中删除视图,并每次都将其重新插入。 在所有这些过程中,视图仍保留在内存中,因此不会重复调用viewDidLoad
。
但是,当您开始在当前屏幕上显示视图时会遇到麻烦,因为有时*它将删除基础视图,但有时*不会。
展示您的View Controller
这完全取决于您如何呈现模态视图。 如果可能的话,iOS倾向于删除基础视图(内存很宝贵)。 但是,如果您的设计师坚持要保留该基本视图,则可以要求iOS通过设置正确的.modalPresentationStyle
来保留它。
您可以选择以下选项,以及关闭后是否在其父视图上触发viewWillAppear
:
.none
的文档说……
“不要使用这种样式来呈现视图控制器。”
他们通过崩溃强制执行此操作。 感谢Apple让我们保持警惕!
备用计划
当下面的视图保留时,关闭叠加视图时将不会调用viewWillAppear
。 要开展业务,您必须在dismiss
呼叫中加入完成处理程序。
将引用传递给呈现的视图控制器的最佳方法是什么? 这确实取决于您如何设置应用程序,这超出了本文的范围。
缺失的环节
当我们将视图添加到窗口的视图层次结构时,iOS如何知道要通知哪个UIViewController
? 从UIViewController
文档中,我们可以看到它具有对其拥有的view
的引用,但是UIView
文档中没有任何内容表明它知道哪个UIViewController
拥有它。
这些present
方法也没有什么特别的事情发生-即使直接添加视图, viewWillAppear
调用也会发生。
仅仅因为苹果不告诉我们发生了什么,并不意味着我们就无法做出有根据的猜测。 让我们偷偷摸摸,检查专用API…
查看所有这些额外的属性! 而且只有一种具有我们要寻找的类型…… UIViewController* _viewDelegate;
让我们通过创建2个视图控制器进行测试。 我们将一个注入到另一个view
的_viewDelegate
中,并将该view
添加到窗口的视图层次结构中时,应调用注入的视图控制器的viewWillAppear
。
自己尝试一下!
警告 —请勿使用私有API交付应用程序。 这是一种危险的编码方式。 这些属性是私有的,Apple保留在不通知您的情况下随时更改其基础实现的权利。
Sean在 Livefront中度过 了自己最好的iOS生活 。
*有时 对软件开发人员来说是一个非常令人讨厌的词