我滥用UIViewController子类?
在试图找出为什么viewWillAppear没有在我的应用程序中被调用时,我发现可能是我对UIViewController子类的打算使用的严重误解。
根据下面的帖子,viewWillAppear在使用addSubView时不会运行! 以及此博客文章的链接:http://blog.carbonfive.com/2011/03/09/abusing-uiviewcontrollers/ UIViewController子类只能在非常特定的情况下发生。 最值得注意的是,直接添加到UIWindow或其他Apple创建的自定义控制器(如UINavigationControllers)时。
我当然有罪,将UIViewController子类的视图添加到其他UIViewController子类的视图中。
事实上,我认为这或多或少是苹果公司实施MVC的总体思路......一家总体风险投资公司与其他风险投资公司一起,都很乐意让他们的委托方法得到调用。
如果在这篇文章中描述的模型中有很多视图(根据定义需要控制)在应用程序中进入和运行很多screenfull,则每个screenfull应该有一个主VC子类,而所有子视图都由自定义控制器(这恰好控制视图)是简单NSObject的子类。
在这种情况下,UIViewControllers应该只能直接指向Window或UINavigationController,UITabBarController等?
你保证在这种情况下获得UIVC委托方法吗? 这与当viewcontroller的视图是另一个VC的子视图时手动调用委托方法有何不同?
老实说这似乎是对时间的极大浪费。 ViewDidLoad,viewDidLoad,viewDidUnload,viewWillAppear,viewWillDisappear的自定义实现不会提到像“视图”等属性一样简单的事情...
所以基本上,无论我是完全错误的,还是我在疯狂追逐。 如果不能指望UIViewController子类调用viewWillAppear,那么为什么不手动调用该方法,并使用它呢?
为什么要复制UIViewController的所有感知功能?
对题目问题的回答: 是的。
所以基本上,无论我是完全错误的,还是我在疯狂追逐。
这听起来像你是完全错误的。 术语“视图”有一些不同但相关的含义:
听起来你的误解就是最后一点。 视图控制器应该管理一个“屏幕”内容。 如果您使用单个视图控制器对象来管理多个视图层次结构,或者如果您使用多个视图控制器来管理同一视图层次结构的不同部分,那么您使用的UIViewController是从未打算过的,这很可能导致问题。
你提到的方法(-viewDidLoad,-viewWillAppear等)是为了告诉视图控制器它的视图层次结构刚被加载,即将被显示等等。 它们实际上不是指单个子视图,而且视图控制器需要为每个子视图提供这些信息是不常见的。 如果视图层次结构被加载,那么视图控制器知道该层次结构中的所有内容都已加载。
您似乎将这些方法解释为委托方法,但它们不是。 委托是一个独立的对象,可以在不需要子类化的情况下自定义委托。 -viewDidLoad
和-viewWillAppear
是UIViewController覆盖点的两个示例,它是用于子类化的类。 视图控制器对象本身会调用这些方法,以使子类有机会在控制器生命周期中的一个有趣点进行一些操作。
如果不能指望UIViewController子类调用viewWillAppear,那么为什么不手动调用该方法,并使用它呢?
仔细看看UIViewController,你会发现提供的大多数功能都与在屏幕上显示视图(即视图层次结构)有关,或者将控制器与“容器”视图控制器集成在一起,例如UINavigationController和UITabBarController。 这些对于不管理整个屏幕内容的对象都没有用处。
有时会发生一组视图会在多个屏幕上复制,并且在某些情况下,使用与视图控制器本身分离的对象来管理这些视图会很有帮助。 我可以看到你如何使用UIViewController,因为它的-viewDidLoad和类似的方法,但这些只是UIViewController的一小部分。 调用-presentModalViewController:
这些对象之一是什么意思? 或者访问其navigationController
或parentViewController
属性?
如果你真的想使用这些方法来管理你的视图控制器的视图层次的子视图,可以创建一个NSObject的子类,它具有-viewDid [Load | Unload | Appear | Disappear]和-viewWill [Appear | Disappear]方法。 您可以创建该类一次,然后根据需要对其进行子类化,而且任何“子控制器”类都不会拥有UIViewController附带的所有额外的,不必要的控制器管理工具。
编辑:我想在这里添加一个指针给苹果公司的视图控制器编程指南为iOS,它提供了很多支持我上面的布局。 以下是标题为“视图控制器管理视图层次结构”的小节中的相关内容:
视图控制器直接与单个视图对象关联,但该对象通常只是视图控制器管理的更大视图层次结构的根视图。 视图控制器充当视图层次结构的中央协调代理,处理其视图和任何相关控制器或数据对象之间的交换。 单个视图控制器通常管理与单个屏幕的内容相关的视图,但在iPad应用中并不总是如此。
任何人甚至想写一个iOS应用程序都需要阅读视图控制器编程指南。 如果你有一段时间没有阅读过(或曾经),值得回顾一下。
更新:从iOS 5开始,现在可以定义自己的容器视图控制器,即管理其他视图控制器的视图控制器,并可能同时显示多个视图控制器的视图。 您可以在标题为“创建自定义容器视图控制器”部分的上面链接中详细了解它。 这些都没有改变上面的要点:单个视图控制器仍应该管理视图层次结构,像-viewDidLoad
这样的方法仍然引用整个视图图表而不是单个子视图。 视图控制器管理“整个屏幕”内容的建议不再完全准确 - 就像UISplitViewController
在iPad引入后同时显示来自两个视图控制器的内容一样,您自己的容器现在可以显示多个视图子视图控制器。 编写一个容器视图控制器是一个有点高级的话题 - 你应该非常熟悉视图控制器的使用,以及提供的容器视图控制器的工作方式,然后再试图创建自己的视图控制器。