本文翻译自:
https://developer.apple.com/library/content/featuredarticles/ViewControllerPGforiPhoneOS/index.html#//apple_ref/doc/uid/TP40007457
由于对内容理解程度不够深入,翻译内容难免有不当之处还望指正。
- PS:下文中用 VC 代表 view controller
View Controllers 是你的应用内部结构的基础,每个应用至少有一个 VC 大部分应用有多个 VC的。每个 VC 管理你的应用的用户界面的一部分以及底层数据和用户界面之间的交互。VC 也有助于在你的应用的用户界面之间进行切换。
因为 VC 在你的 app 中扮演如此重要的角色,VC 几乎是你所做一切工作的核心. UIViewController
类定义了管理 view 的方法和属性,处理事件,从一个 VC 切换到另一个 VC,他也协调你 app 的其他部分。你定义 UIViewController
的子类(或者其子类之一)并且你需要添加实现你的 app 的 行为的自定义代码。
这里有两种类型的 VC:
- Content View controller管理你应用的一部分 并且是你创建的 VC 的主要类型
- Container view controller 从其他视图控制器(称为子视图控制器)收集信息,并且以 导航栏或者
prsent
的这样便利的方式呈现不同地视图控制器的内容。
大多数 VC 是这两种类型的混合。
视图的管理
视图控制器最重要的角色是管理视图的层次结构。每个视图控制器有一个 根视图(root view)它包含了视图控制器的所有内容,你在根视图中添加用于展示内容的视图。图 1-1
展示了视图控制器和视图之间的内在关系。视图控制器总是有对其根视图的引用并且每个视图对齐子视图都是强引用。
图1-1 视图控制器和其视图之间的关系
注意
在你的视图控制器层级中使用outlets
去访问其他视图是常用的方法,因为一个视图控制器管理所有视图的内容,outlets
可以让你存储你需要的视图的引用。当视图从storyboard
加载的时候,outlets
本身自动的链接到实际的视图对象。
- 译者注:outlets 用IBoutlet 注解的属性,在 类接口中声明 outlets 然后和 storyboard 中的对象进行连接,当 storyboardd 加载时候这个连接被建立)
一个内容视图控制器自己管理其说有的视图,一个容器视图控制器(container view controller)管理其自己的视图以及来自其一个或多个子视图控制器的根视图。容器视图控制器不管理他子视图的内容。它只管理根视图,根据容器的设计进行尺寸调整和位置的摆放。图1-2 显示了一个视图分割的视图控制器和他子视图之间的关系。这个分割的视图控制器管理管理其子视图的整体的大小和位置,但是子视图控制器真正管理这些视图的内容。
图1-2 视图控制器可以管理其他视图控制器的内容。
关于管理视图控制器的视图的信息可以查看 Managing View Layout
- 译者注:如图所示,容器视图控制器(Split View Controller)管理自己视图(Split View Container View )和 来自其他多个视图控制器的根视图 (View Controller A/B),然后视图控制器再去管理自己视图的内容 A/B 的内容。
数据封送
一个视图控制器充当在它管理的视图和你应用的数据之间的媒介。UIViewController
类的属性和方法可以让你管理你的应用的视觉呈现。当你继承UIViewController
后,你可以在你的子类中添加任何你需要用来管理数据的变量。添加自定义变量会创建一个如图1-3 所示的关系,其中视图控制器具有对你数据的应用以及用于呈现数据的视图。在这两者直接来回移动数据是你的工作。
图1-3 视图控制器在数据对象和视图之间调解
你应该始终在视图控制器和数据对象中保持清晰的职责分工。大多数的确保数据结构完整性的逻辑属于数据对象的本身。视图控制器可以校验来自视图的输入然后以数据对象需要的格式打包输入,但是你应该最小化视图控制器在管理实际数据中的角色。
UIDocument
对象是一个独立于视图控制器来管理你的数据的方式。一个文档(doucument)对象是一个控制器对象,它知道如何读取和写入数据到持久化存储当中。当你继承 UIDocument
时候,你可以添加所需的任何逻辑和方法来提取数据,并将其传递给视图控制器或应用程序的其他部分。视图控制器可以存储他接受的任何数据的副本,以便更新视图,但文档仍然拥有真实的数据。
用户交互
视图控制器是响应者(responder) 对象 ,能够处理响应者链中传递下来的事件。尽管他们都能够处理事件,视图控制器很少直接处理触摸事件。相反,视图经常处理他们自己的触摸事件然后将结果报告给关联的委托(delegate)或目标对象(通常是视图控制器)的方法。所以视图控制器的大多数事件都是使用委托方法或操作方法处理的。
关于在视图控制器中实现操作方法的更多信息,请查看Handling User interractions.有关处理其他类型的事件,请查看 Event handling Guide for iOS
资源管理
视图控制器对其视图和它创建的任何对象承担全部责任。 UIViewController
类自动处理视图管理的大多数方面。举个例子,UIKit 自动释放不在需要的任何视图相关的资源。在你的 UIViewController
子类中,你负责管理你明确创建的任何对象。
当可用空闲内存不足时,UIKit 要求应用程序释放不在需要的资源。一种方式是通过调用视图控制器的 didReceiveMemoryWarning
方法。用这个方法移除不再需要的对象的引用或者稍后可以轻松重新创建。例如,你可能用这个方法删除了缓存数据,当低内存条件发生的时候,他是一个你能够释放更多内存的重要方法。应用消耗太多内存的话可能被系统恢复内存彻底终止。
适应性
视图控制器负责呈现其视图,并使该呈现适应底层环境。每个 iOS 应用应该能够在 iPadshang运行,并且可以在几种不同大小的 iPhone 上运行。而不是为每个设备提供不同的视图控制器和视图层次结构。使用单一视图控制器管理视图使其适应不断变化的空间要求更为简单。
在 iOS 中,视图控制器需要处理粗粒度编号和细粒度变化。粗粒度变化发生在视图控制器特征的变化。特征是描述整个环境的属性,像显示的比例。两个重要的特征是视图控制器的水平和垂直尺寸类别,它表示视图控制器在给定维度有多少空间。你可以使用尺寸类别的变化来更改你布局视图的类别,像 图1-4 显示的那样。当尺寸种类是 regular
时候,视图控制器利用额外的空间去管理它的内容,当是 compact
时候,视图控制器垂直排列其内容。
图1-4 调整视图大小类的变化
在给定的尺寸级别类中,任何时候都可能发生更细粒度的尺寸变化。当用户将 iPhone 从纵向旋转到横向时,尺寸类别可能不会改变,但是屏幕尺寸通常会改变。当你使用自动布局时候,UIKit
自动调整视图的大小和位置去匹配新的屏幕大小,视图控制器可以需求进行其他调整。
有关更多的适应性的信息,请查看The Adaptive Model