我刚刚开始开发iPhone应用程序,我对用户界面的“视图控制器”方面如何工作感到困惑。
我在开发中心做了“你的第一个iPhone应用程序”教程。它让您设置自己的视图控制器类,然后使用initWithNibName对其进行初始化。所以似乎nib文件包含视图控制器。但是也可以有一个只有视图的nib文件,而不是视图控制器。例如,如果你设置一个TabBarController然后导航到除第一个之外的任何选项卡,那么会有一个灰色的框显示“view”,如果你双击那么你可以设置一个视图进入该选项卡(但它只是一个视图,而不是视图控制器,我是对的吗?)视图控制器的视图子类也是如此,反之亦然?
我理解的另一件事是嵌套视图控制器。我理解你使用视图控制器(至少从教程中)的方式是你创建自己的自定义视图控制器(或者它实际上是一个视图控制器?在教程中我没有看到myViewController实际声明扩展到哪里UIViewController)中包含所有委托方法,然后使用initWithNibName将现有视图控制器加载到自定义视图控制器中。 (到目前为止?)所以假设我在根目录下创建了一个带有TabBarController的nib文件,当然每个选项卡都有一个根视图控制器。然后我将loadWithNibName文件加载到我自己的根视图控制器中。现在我如何访问所有“内部”视图控制器,以便我可以为它们分配委托方法?或者是建议的选项,使根视图控制器成为其自己的视图和所有辅助视图控制器的视图的委托?
这是另一个例子。我打算有一个TabBarController,对于某些选项卡,该选项卡的视图控制器将是一个NavigationController。我理解导航控制器的方式是,当您想要在层次结构中向下钻取时,必须以编程方式将视图推送到堆栈顶部。假设我推送的视图是我最初在Interface Builder中创建的视图(并使用initWithNibName加载)。但是当我创建视图时,显示视图的空间小于视图可用的空间(因为我创建时)它是在一个空白的平板上,而当我显示它时,有一个导航栏和一个标签栏用尽了一些屏幕。)那么视图控制器会自动调整视图大小以进行补偿吗? (IIRC,文档的一部分确实提到了自动调整大小,但似乎自从宽高比改变后,缩放到正确的大小会使文本看起来“被压扁”。)
最后是否有一些教程或解释清楚地解释了视图控制器的工作原理?这也可以帮助我回答我的问题。
答案 0 :(得分:10)
(1)Apple's UIViewController
reference。短而甜(相对)。
(2)View Controller Programming Guide for iPhone OS。更罗嗦。
(3)不查看控制器特定,但仍然是:Cocoa Dev Central。教育与漂亮的图片。
事实是,在介绍性文档中有一些关键点有点掩盖。我认为,特别是使用标签栏控制器和导航控制器会产生很多混乱。
例如:
您不应该使用视图控制器来管理仅填充其窗口一部分的视图 - 即,只是应用程序内容矩形定义的区域的一部分。如果您想要一个由几个较小视图组成的界面,请将它们全部嵌入到一个根视图中,并使用您的视图控制器管理该视图。
- UIViewController
课程参考
所以,这肯定会让你觉得你永远不应该嵌套视图控制器,对吧?嗯,根据我的经验,他们意味着所说的更像是永远不会嵌套视图控制器,除了可能在标签栏控制器,导航控制器或导航控制器中标签栏控制器。但除此之外,永远不要嵌套视图控制器。
你提出的另一个好问题是:编码器负责调整视图大小,还是由视图控制器完成?通常的答案是:是的,编码器负责视图元素的所有布局和精确大小 - 除了,当该视图是第一个添加到标签栏或导航控制器的视图时 - 它们倾向于有点积极地为你调整你的观点。还有更多细节要知道 - 如果方向发生变化,可以自动调整视图 - 但这是一个很好的经验法则。
视图和视图控制器都不是彼此的子类。他们是独立的人。通常,视图控制器更负责,并且告诉视图要显示什么数据,或者在哪里定位自己等。视图并不真正告诉控制器做什么,除非可能告知用户操作,例如一个UIButton
在推送时调用其控制器中的方法。
这是一个快速类比,以帮助理解整个MVC模型。想象一下,你正在为汽车构建UI。您需要构建一个仪表板来向驱动程序显示信息 - 这是视图。您需要传感器来了解它的运行速度,燃气量以及无线电台的用途 - 这些数据和直接数据处理的东西就像模型对象。最后,您需要一个系统,该系统知道何时打开低燃气灯,或者当您将车轮转得足够远时关闭转向信号,以及所有类似的逻辑 - 这是控制器组件。
nib文件主要是一种保存视图相关数据的方法,这些数据会导致丑陋的代码。您可以将它们逻辑地视为冻干类实例,随时可以使用。例如,定位20个按钮的网格,这些按钮将成为计算器的UI;一堆像素坐标会产生无聊的代码,并且在界面构建器中更容易使用。它还可以容纳视图控制器,因为该代码偶尔也是样板 - 例如当您需要标准的日常标签栏控制器时。
关于哪些视图控制器控制哪些视图:同样,标签栏和导航控制器是一种特殊情况,因为它们可以充当其他视图控制器的容器。默认情况下,您认为一次只有一个视图控制器负责全屏,在这种情况下,毫无疑问,这个视图控制器正在处理从您的视图或其他元素返回的任何委托调用。如果你做有一些容器视图控制器,那么对于最具体的视图控制器(最嵌套的一个)来说,做所有脏工作仍然是有意义的,至少对于那些不是由容器控制器控制(即任何不是标签栏/导航栏)。这是因为容器视图控制器通常不被认为是知道它们包含的内容,而这种不可知性为我们提供了更好的解耦和更易维护的代码。
而且,是的,在此上下文中,视图控制器始终是UIViewController
的子类。
答案 1 :(得分:0)
视图控制器就是 - 处理视图控制的对象。
XIB文件不包含视图控制器。相反,它通常会告诉XIB,最终将连接到哪个视图控制器 - 这是initWithNib调用正在执行的操作,创建视图控制器,从xib获取视图,然后将视图控制器附加到XIB所说的位置它应该连接到视图的部分。
当您使用导航控制器或标签栏时,技术上存在嵌套视图控制器,但您自己的视图控制器基本上被调用,就像它是顶层一样,因为这些容器理解它们将持有其他视图控制器。
至于调整大小 - 它不是像素大小调整,它是一个容器调整大小。视图控制器调整其连接的主视图的大小,然后视图保持的任何元素的自动调整大小行为决定了它们的大小调整 - 像标签这样的一些东西可能会移动,但默认情况下不会缩小。如果单击IB中的“标尺”选项卡,则可以看到视图中任何对象的当前自动调整行为 - 两端带箭头的中心线告诉您对象是否允许调整大小以及在哪个方向上。方形外侧的线条告诉您物体将“粘住”哪一侧,这意味着无论容器如何调整大小,物体都将与这些边缘保持相同的距离。
我不确定IB的最佳书籍是什么,但你可能不会错误地找到一本好的基础Cocoa书籍来解释自动化行为。