本节书摘来自华章计算机《Swift iOS应用开发实战》一书中的第3章,第3.4节,作者:刘铭 著, 更多章节内容可以访问云栖社区“华章计算机”公众号查看。
3.4了解视图控制器
通过Calculator项目我们可以体会到,每个视图控制器都会负责管理iOS应用程序中的一个独立视图,响应用户在该视图中的操作。但是不仅如此,在需要的时候,它还要负责与其他视图控制器的切换以及在控制器间的数据传递。比如iOS中的通讯录程序,当用户点击某个联系人(单元格)的时候,当前控制器A要负责切换到另外一个控制器B(负责显示联系人详细信息的视图控制器)。
3.4.1视图控制器简介
到目前为止,你应该明白视图控制器的作用了。简单来说,它就像是iOS应用程序中所实现的每个功能的核心组件,将视图和数据模型紧密连接在一起,用Model所提供的数据“装填”视图。
在Calculator项目的ViewController类中,我们可以看到viewDidLoad和didReceive-MemoryWarning方法。其中第一个方法会在载入视图后执行,而第二个方法则会在收到内存警告的情况下执行。通过重写这些方法,可以帮助我们更好地管理控制器。
上面提到的两个方法在控制器的生存期(注意,不是生理期)内有效,理解控制器的生存期可以帮助我们正确管理其所包含的数据模型和视图。如果你对生存期有足够的了解,就可以让控制器在载入视图时做些事情,或者是在移除视图时完成一些任务。正确理解生存期将是成为一名优秀iOS程序员的基础,因为控制器是解决一切问题的核心。
当应用程序运行到某个指定的视图控制器以后,控制器就要将其自己的视图对象显示在屏幕上,这会引发一系列的事件。如果该视图控制器的视图属性还没有被入内存中,控制器将调用loadView方法。当载入视图完成,就会调用viewDidLoad方法,在这个方法里面我们可以对需要显示的数据进行初始化,如图3-6所示。
如果你愿意,完全可以在控制器中重写loadView方法,通过编写代码的方式创建控制器的视图,这种方式与我们在Calculator中通过故事板的方式正好相反。
表3-1列出了一些方法,这些方法在整个视图控制器生存期中是由不同的视图事件所触发的,它可以让你更精确地控制视图控制器在不同状态时需要完成的事情。
为了验证控制器生存期中的方法,我们在ViewController类中重写两个方法。
步骤1在项目导航中选择ViewController.swift,在-viewDidLaod方法的最后添加下面一行代码:
println("viewDidLoad 被调用")
步骤2在-viewDidLaod方法下面添加如下两个方法:
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
println("viewWillAppear 被调用")
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
println("viewDidAppear 被调用")
}
构建并运行应用程序,在控制台中我们会看到如下输入信息:
viewDidLoad 被调用
viewWillAppear 被调用
viewDidAppear 被调用
从输出结果我们可以发现,-viewDidLaod是第一个被调用的方法,第二个是-viewWill-Appear,第三个则是-viewDidAppear。在调用-viewDidLaod方法之前,视图控制器还会检测是否有-loadView方法被重写,Calculator项目并没有重写-loadView方法,完全是通过故事板载入的控制器视图。这里我们不再去重写-viewWillDisappear和-viewDidDisappear方法,因为只有载入另一个控制器的时候,当前控制器的这两个方法才会被调用。
虽然在Calculator中我们只使用了一个视图控制器,但是苹果还为我们提供了很多不同类型的控制器,方便我们开发应用程序。
3.4.2不同类型的视图控制器
苹果提供了多种不同类型的视图控制器来实现应用程序的一些常用功能,比如帮助我们将数据布局到表格视图或者网格中。另外,这些控制器也能够管理其他的视图控制器,从而让用户以标签栏或先后结构层次的形式有序地呈现控制器。表3-2列出了这些控制器。
其实,在上面表格中所列出的视图控制器我们都不会陌生,因为iOS中的原生应用全部用到了它们,接下来我们就逐一开始介绍。
- 导航控制器
导航控制器(navigation controller)是以层级结构的形式来管理其堆栈中的多个视图控制器。在导航控制器中,我们把其中的第一个视图控制器叫做根视图控制器(root view controller)。当导航控制器显示视图时,我们可以将另外一个视图推送进栈。导航控制器允许我们一级级地退出当前视图控制器,直至退回到根视图控制器。图3-7显示了“设置”应用程序中的导航控制器。
iOS的“设置”应用程序使用了导航控制器,当我们点击“通用”以后,一个新的视图会被推送到navigation controller的堆栈中并显示在屏幕上面。在屏幕的左上方还有一个返回按钮,可以让我们直接返回到之前的视图,或者点击其他控件进入更深层次的视图。
- 标签栏控制器
标签栏视图控制器(tab bar view controller)提供分割不同的视图控制器的一种简单方式。标签栏是该控制器的标志元素,苹果的“电话”应用程序就使用了标签栏控制器,如图3-8所示。
标签栏中可以包含若干个标签条目(tab bar item),每个标签条目则包含一个图标和一个标题,用于构建标签条目的外观。每个标签包含一个独立的视图控制器,比如可以在标签中包含一个导航控制器,就像“电话”中的“通讯录”。
- 表格视图控制器
表格视图控制器(table view controller)包含了一个单独的表格视图。表格视图允许我们以单元格的形式一行行地显示数据信息,并且还可以对数据行进行分组。
图3-9显示了一个表格视图控制器的样子,如果需要,我们还可以将其分组为多个部分。