控制器简介
UIKit 中的视图
UIKit 中的视图继承自基类UIView。视图有多种类型,例如按钮、滑块、列表、网格等等。我们可以直接使用 UIView,也可以继承它,或者使用它的子类。
UILabel
这是一个文本标签。
其中一些较常用的成员:
- text: 字符串- 定义标签显示的文本。
- textColor:UIColor - 它定义标签的文本颜色。
- font: UIFont - 它定义标签使用的字体。
UI按钮
这是一个带有文本标签的按钮。我们可以自定义它被点击时的行为(稍后会详细介绍)。
其中一些较常用的成员:
- setTitle(_:for:) - 修改按钮标签内的文本。
- setTitleColor(_:for:) - 修改按钮标签的文本颜色。
对于它们俩,在for参数中,我们使用 .normal。
UIImageView
这是一张带有图像的风景照。
其中一些较常用的成员:
- image: UIImage - 定义视图显示的图像。
- contentMode: ContentMode - 定义当图像大小不相等时,图像将如何适应此视图。
ContentMode最常用的值:
UITextField
这是一个显示可编辑单行文本的视图。
其中一些较常用的成员:
- text: 字符串- 定义文本字段显示的文本。
- textColor:UIColor - 定义文本字段的文本颜色。
- keyboardType: UIKeyboardType - 定义与文本字段交互时将显示的键盘类型。
- isSecureTextEntry: Bool - 定义是否将文本字段显示为密码字段,其中使用点而不是字符。
UIStackView
这是一个可以显示其他视图的视图。
- 它允许我们按垂直或水平轴对视图进行排序。
- stackView 的子视图不需要约束,但它需要约束才能在其容器内显示自身。
UIViewController 生命周期
什么是生命周期?
生命周期是指定义一个对象从创建到销毁的一系列状态。
对于控制器或视图,我们不允许修改其生命周期状态,但我们可以对这些变化做出反应,并自定义视图或控制器状态改变时发生的情况。
每当一个对象改变其状态时,就会执行一个生命周期方法(或简称钩子)。我们可以重写这些方法中的任何一个,以自定义在这种情况下要发生的情况。
上图显示了视图控制器生命周期中的不同方法以及它们之间可能的转换。
在本课程中,我们将只了解最重要的状态和转换。
init方法会在控制器实例化时执行。此时,视图尚未加载到内存中。如果此时尝试访问视图中的元素,应用程序将会崩溃。请务必小心。- viewDidLoad:当控制器中的视图加载到内存后,此方法将被执行。它在整个控制器生命周期中只会执行一次。
- viewWillAppear:当控制器中的视图显示给用户时,此方法将被执行。在控制器的生命周期内,此方法可以执行任意次数。
- viewDidAppear:此方法会在视图显示在屏幕上后执行。如果应用使用动画过渡效果导航到另一个视图,则此方法会在过渡动画完成后执行。此时,视图的约束条件将具有实际值。
- viewWillDisappear / viewDidDisappear:它们类似于viewWillAppear和viewDidAppear,但方向相反。
@IBOutlet 和 @IBAction
财务主管有两项职责:
- 要将数据从模型发送到视图:可以通过为控制器可以访问的视图设置属性来实现。控制器必须拥有对其视图的引用。这些引用是简单的隐式解包的可选变量,并带有
@IBOutlet注解。因此,@IBOutlet注解表示带有此注解的视图将链接到界面生成器中的一个视图。 - 为了在模型中反映用户操作:这可以通过在控制器中使用
@IBAction注解的方法来实现,这些方法将与视图中的操作(例如按钮点击)关联起来。除了使用@IBAction之外,还有其他方法,但这对于入门来说已经足够了。
假设我们有这样的视图:
我们需要在控制器中添加的功能是响应UIButton中“生成全名”的点击事件,以便我们可以获取UITextField视图中用于输入名字和姓氏的文本属性,并替换 UILabel中显示“全名”的文本。************
为此,我们需要在控制器中添加以下引用:
- firstNameTextField: UITextField!
- lastNameTextField: UITextField!
- resultLabel: UILabel!
为什么这些是可选的?因为当我们实例化控制器时,视图还没有加载!我们可以通过执行viewDidLoad方法来判断视图何时实例化。这一点 非常重要,它可以避免程序随机崩溃。
生成 @IBOutlet
- 在右侧打开编辑器。
- 在正确的编辑器中,打开ViewController.swift类。****
- 在左侧编辑器中,搜索您想要链接的视图。
- 按住键盘上的控制键,将视图拖放到控制器代码的任何位置(方法内部除外)。
确保此操作正确生效的一个简单方法是,在左侧编辑器中选择视图控制器。在右侧面板的最后一个选项卡中,我们将看到已链接的 @IBOutlet和 @IBAction的名称。
除了 @IBOutlet之外,我们还需要使用 @IBAction对 UIButton中的操作做出反应,正如我们已经了解到的,它是一个在视图中发生某些操作时将执行的方法。****
@IBAction func generateNameButtonPressed() {
// ...
}
按钮的@IBAction可以关联到该按钮的不同事件。通常,我们会使用touchUpInside事件,这是按钮上最标准的点击事件。
生成@IBAction的步骤与生成 @IBOutlet 的步骤完全相同,只是在最后一步中,我们需要选择一个 action 而不是一个 outlet。
视图和事件连接完成后,我们就可以在控制器中插入自定义逻辑。在本例中,我们需要从UITextField视图中获取名字和姓氏,然后将它们连接起来,赋值给 UILabel 的 text属性。
实践
创建一个应用程序,屏幕中间只有一个带有0 (零)的标签,标签上有两个按钮,左侧的按钮用于递减标签的值,右侧的按钮用于递增标签的值。
另外……如果我们添加一个文本字段来自定义按下按钮时要增加或减少的数值,会怎么样?