本章,你将链接FoodTracker应用程序的UI到代码并定义一些可执行的动做。当你完成时,你的应用程序将是这个样子:编程
学习目标
在课程结束时,你将可以:
1.解释一个storyboard中的场景和view controller之间的关系
2.在storyboard中UI元素和源代码建立出口和链接动做
3.从文本字段处理用户输入并在UI中显示结果
4.使用一个类遵循一个协议
5.理解委托设计模式
6.在设计应用程序体系结构时,按照目标 - 动做模式swift
链接UI到源代码设计模式
在storyboard的元素连接到源代码。重要的是要了解storyboard和你写的代码之间的关系。在storyboard中,一个场景表明的一个内容屏,一般一个视图控制器。视图控制器实现您的应用程序的行为。视图控制器管理单个内容视图和编辑器
它的子子视图的层次。视图控制器在应用程序的数据模型之间协调信息流,它封装应用程序的数据,而且显示数据,管理其内容视图的生命周期,该设备被旋转时,处理方向改变,定义应用程序的导航,并响应用户输入的行为。在全部的ide
iOS视图控制器对象类型为UIViewController或其子类。经过建立和实现自定义视图控制器子类来在代码中定义您的视图控制器的行为。而后,您能够建立你的storyboard,让你在代码中定义的行为,你在storyboard中定义的UI,并性能
把这些类和场景链接起来。Xcode中已经建立了这样一个类,就是ViewController.swift,并将在storyboard中其链接到你工做的场景。在将来,当你添加更多的场景,你能够经过Identity inspector来连接。Identity inspector能够学习
在storyboard中编辑,你能够指定某个类和storyboard关联起来测试
在运行时,你的storyboard将会建立一个ViewController的实例,你自定义的视图控制器的子类。你在APP中看到的屏幕会在场景中显示UI定义并在ViewController.swift中定义行为。虽然场景链接到了ViewController.swift,这不是须要作的惟一的链接。要和你的APP互动,你的视图控制器源代码须要能和View沟通。在storyboard中的view和视图控制器源代码文件之间,你经过定义额外的链接,如调用出口和动做动画
建立UI元素出口ui
出口(Outlet)提供一个方法来引用界面对象,前提是这些对象已经在你的storyboard中。为了建立一个outlet,在storyboard中从一个指定对象控制拖动到一个视图控制器文件。这个操做会为你视图控制器文件中的对象建立一个属性,这个属性能让你在运行时的代码中访问和操做对象。你须要为文本框和标签建立outlets来引用它们,步骤以下:
1.打开你的storyboard,Main.storyboard
2.点击Assistant按钮打开assistant editor,它在Xcode的顶部右边
3.若是你想要更多空间,你能够折叠navigator,utility和outlin 区域,
4.在editor selector bar中顶部出现的assistant editor,从Preview改为Automatic > ViewController.swift
5.打开ViewController.swift类,添加一行注释// MARK:
6.在storyboard中,选择文本框
7.按下Control的同时拖动画布中的文本框到代码中,在注释那一行中止拖动。以下图所示:
8.在弹出的对话框中,的Name字段后,输入nameTextField,而后就能够了,以下图所示:
IBOutlet属性告诉Xcode,你能从Interface Builder链接到
nameTextField属性(这就是为何属性前缀为IB)。weak关键字表示这个属性可能没有值(nil)。nameTextField表示声明一个
UITextField类的变量,末尾的感叹号表示它是一个可选也能够是非可选的值,不须要每次访问时,展开这个可选值,由于他假定老是有一个初始化的值,如今以相同的方式把标签也链接到代码。
@IBOutlet weak var mealNameLabel: UILabel!
定义要执行的动做(Action)
iOS应用程序都是基于事件驱动编程。系统事件和用户动做:即,应用程序的流由事件决定。用户在界面中执行动做来触发的应用程序的事件。这些事件致使应用程序执行逻辑和操做它的数据。该应用程序的响应用户的操做,而后反射回UI中。因为用户,而不是开发者,用户只会触发一些动做,但到底哪些动做你想处理,你就能够写对应的动做处理代码。通常对于用户的动做,咱们须要友好的响应。一个动做(或动做方法)是一段代码,它能够链接到发生在你应用程序中的事件。当该事件发生时,代码被执行。你能够定义一个操做方法,从操纵一个数据来更新UI。你使用动做来驱动APP的流程,为了响应用户或系统事件。你建立一个outlet,就是以一样的方式建立一个动做:在你的storyboard中,Ctrl+拖动一个特定的对象打牌视图控制器文件中。此操做会在你的视图控制器的文件中建立方法,当用户和对象交互时,动做的方法会被触发。首先建立一个简单的动做,当用户点击Set Default Label Text按钮时,设置标签的值为Default Text,接下来让咱们写这个动做:
1.在最后一个大括号的前面写下以下注释
// MARK: Actions
这个注释表示这段代码会执行动做
2.在你的 storyboard中,选择Set Default Label Text按钮
3.按住Control键拖动画布中的按钮到右边的编辑器中的代码上,在你尴刚才注释的代码上中止拖动
4.早弹出的对话框中的Connection字段右边选择Action
5.Name字段右边,键入setDefaultLabelText
6.Type字段右边,选择UIButton
你可能注意到Type的默认值是AnyObject,在Swift中AnyObject是一个类型,它用于描述一个能够输入任意类的对象。指定动做的类型为UIButton意思是仅仅只有按钮对象能链接到这个动做。虽然对你如今建立的动做没有意义,但记住它是颇有必要的,未来会用到,这时你的对话框应该以下图所示:
7.点击connect
Xcode会添加代码到你的ViewController.swift中
@IBAction func setDefaultLabelText(sender: UIButton) {
}
sender参数指向触发动做的对象,当前状况下是一个按钮。IBAction属性是表示这个方法是一个动做,你能从storyboard中链接到Interface Builder。剩余的
setDefaultLabelText只是一个方法名。如今方法体中没有代码,实现重置标签的代码是很简单的。下面让咱们来实现这个动做:
a.在ViewController.swift中找到你刚添加的setDefaultLabelText动做方法
b.在方法中实现以下代码:
@IBAction func setDefaultLabelText(sender: UIButton) { mealNameLabel.text = "Default Text" }
你可能猜到了,这个代码是设置标签文本的默认属性。text是标签对象中的属性。注意,你没必要指定默认文本的类型,由于Swift中能够正确类型推断出它的类型。
检查点:测试你的代码,运行模拟器。当你单击Set Default Label Text按钮时,标签会从Meal Name变成Default Text。
你刚才实现的行为是在iOSAPP设计target-action模式的一个例子。target-action设计是当特定事件发生时的其中一个对象将消息发送给另外一个对象。在本例中,该事件是用户轻敲Set Default Label Text按钮,动做是setDefaultLabelText方法,目标的ViewController(定义动做方法的地方),而发送者是Set Default Label Text按钮。该消息是在源代码中定义的方法,目标是接收消息的对象,同时它也是一个可以执行动做的对象。发送动做消息的对象一般是一个按钮,滑块,或开关,能够响应于用户交互动做,如点击,拖动。这种模式在iOS应用程序中很是广泛的,你会在后面看到更多。
处理用户输入
在这一点上,你必须有一个能从新设置标签的默认值的一种方式,而如今你已经会添加行为,来设置文本框的值。为了简单起见,你会依赖于用户点击文本框键盘上的Return 键的动做,指示标签将会更新。
当您从文本框接受用户输入时,则须要从文本框委托一些帮助。委托是一个表明动做的对象,或另外一个对象协调配合。在这种状况下的委托对象是文本框,委托对象将消息发送到委托。该消息告诉该委托有关该委托对象将要处理或刚处理的事件。委托能够响应由例如,更新对象外观或状态,能够是自身也能够是其余对象,或返回一个值,该值做用于一个即将到来的事件的处理方式。
当文字被编辑时,文本框的委托和文本框进行通讯,而且知道在重大事件发生时,好比当用户开始或中止编辑文本。委托能够在正确的时间使用这些信息来保存或清除数据,消除键盘,等等。
任何对象能够做为另外一个对象的委托,由于它符合适当的协议。它定义了一个文本框的委托协议,被称为UITextFieldDelegate。在这种状况下,因为ViewController保持了一个文本框的引用,因此你会让ViewController成为文本框的委托。
首先,你须要有采用UITextFieldDelegate协议的ViewController。你能够经过将其列为类中的一行代码来声明采用一个协议。下面让咱们来看看UITextFieldDelegate协议是如何分配的
1.返回standard editor
2.在项目导航中,选择ViewController.swift文件
3. ViewController.swift找到class这一行,以下所示:
class ViewController: UIViewController {
4.在UIViewController后,添加逗号和UITextFieldDelegate表示采用这个协议:
lass ViewController: UIViewController, UITextFieldDelegate {
经过采用该协议。这意味着你设置了文本框的委托,能够实现它的一些行为来处理文本框的用户输入。
接下来咱们为nameTextField设置ViewController做为一个委托
a.在ViewController.swift中,找到viewDidLoad()方法:
override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. }
该模板此方法的实现,会自动生成注释。你能够删除注释。
b.在super.viewDidLoad()下面添加一行代码
// Handle the text field’s user input through delegate callbacks. nameTextField.delegate = self
self表示ViewController本身。如今
ViewController是一个为nameTextField服务的委托
UITextFieldDelegate协议包含了可选的方法,这表示你没必要实现它们。但你能够得到你想要的指定的行为,你能够还实现这两个方法
func textFieldShouldReturn(textField: UITextField) -> Bool
func textFieldDidEndEditing(textField: UITextField)
为了理解当这些方法的调用时,他们须要作什么,重要的是知道文本框如何响应用户事件,当用户点击文本框,会自动变成首要响应对象。在APP中首要响应对象是首先响应APP事件的对象,包括键盘事件,手势事件,动做消息等。换句话说,许多由用户生成的事件最初都会连接到首要响应
做为文本框变成首要响应事件的结果,iOS显示键盘并开始为文本框编辑会话。经过键盘来键入类容到文本框中
当一个用户想要完成文本框的输入时,文本框须要放弃首要响应状态。由于文本框再也不是APP的当前对象,事件须要传递到更合适的对象中
这是实现UITextFieldDelegate进入方法的地方。当用户点击按钮来结束编辑时,你须要指定文本框放弃它的首要响应状态。你能够在textFieldShouldReturn()方法中这么作,它表示当用户在软键盘上点击Return后的调用。
下面让咱们来实现UITextFieldDelegate协议的textFieldShouldReturn()方法
a.打开ViewController.swift
// MARK: UITextFieldDelegate
该注释用于组织你的代码,并帮助你(和其余读你代码的人)导航。
您已经添加了几个这样的注释了。 Xcode中列出了全部这些注释,做为源代码文件的functions menu中的标题,若是你单击该标题。你的代码快速跳转到一个地方。你会发现跳转到了// MARK:注意冒号必须打
b.在注释下方,添加方法
func textFieldShouldReturn(textField: UITextField) -> Bool {
}
c.在方法中,添加以下代码来放弃文本框的首要响应状态。
// Hide the keyboard. textField.resignFirstResponder()
当你输入res的时候,Xcode强大的代码完成功能,会让你写代码更快,相似Eclipse等须要软件都自带这个强大省时的功能。
d.在方法中,添加以下代码:
return true
由于这个方法返回一个布尔值,返回true表示文本框将响应用户按下的返回键来让软键盘消失
你的textFieldShouldReturn方法看起来会是这样:
func textFieldShouldReturn(textField: UITextField) -> Bool { // Hide the keyboard. textField.resignFirstResponder() return true }
第二个方法是textFieldDidEndEditing(),它在textFieldShouldReturn()以后调用。
textFieldDidEndEditing()方法给你一个机会读取输入到文本框中的信息,并用它作些什么。在本例中,咱们会用文本框中的文原本改变你的标签的值。
func textFieldDidEndEditing(textField: UITextField) { mealNameLabel.text = textField.text }
检查点:测试你的代码,运行模拟器。您能够选择文本框,并输入文本。当你点击键盘上的Done 按钮,键盘消失,标签文字会变成文本框中的文本。当你单击 Set Default Label Text按钮时,标签会显示Default Text