在上一课中 ,您使用Xcode(一个基本的待办应用程序)创建了一个简单的Swift项目。 在本期Swift From Scratch中 ,我们将添加创建待办事项的功能。 在此过程中,您将了解操作,委派和属性。
先决条件
如果您想跟我一起学习,请确保您的计算机上安装了Xcode 8.3.2或更高版本。 您可以从Apple的App Store下载Xcode 8.3.2。
1.添加项目
在本课程结束时,用户将可以通过以下方式添加新的待办事项:点击导航栏中的按钮,显示带有文本字段和按钮的视图。 让我们开始创建一个视图控制器,该控制器将处理添加新的待办事项,即AddItemViewController
类。
步骤1:建立AddItemViewController
从Xcode的“ 文件”菜单中选择“ 新建”>“文件...” ,然后从“ iOS”>“源模板”列表中选择“ Cocoa Touch Class”模板。
将类命名为AddItemViewController
,并确保它继承自UIViewController
。 仔细检查“ 语言”已设置为“ Swift” , 并且未选中“ 同时创建XIB文件” 。
告诉Xcode您要在何处保存AddItemViewController
类的文件,然后单击创建 。
第2步:添加渠道和操作
在创建AddItemViewController
类的用户界面之前,我们需要为文本字段和两个动作创建一个出口,一个为导航栏中的取消按钮,另一个为文本字段下方的创建按钮。
现在应该熟悉添加插座。 在AddItemViewController
类中创建一个插座,并将其命名为textField
,如下所示。
class AddItemViewController: UIViewController {
@IBOutlet var textField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
创建动作与创建实例方法非常相似。 实际上, @IBAction
属性不过是Interface Builder的提示。 通过为方法添加@IBAction
属性作为前缀,我们确保Interface Builder知道该方法,这使我们能够在情节@IBAction
其连接。 现在,我们将两个动作的主体都留空。
class AddItemViewController: UIViewController {
@IBOutlet var textField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
@IBAction func cancel(_ sender: Any) {
}
@IBAction func create(_ sender: Any) {
}
}
步骤3:建立使用者介面
在项目浏览器中打开Main.storyboard ,然后从右侧的对象库中拖动一个View Controller 。 选择视图控制器后,打开右侧的Identity Inspector并将“ 自定义类”>“ 类”设置为AddItemViewController 。
要将导航栏添加到添加项目视图,请选择添加项目视图控制器 并从“ 编辑器”菜单中选择“ 嵌入”>“导航控制器 ”。 这将使“ 添加项目视图控制器 ”成为导航控制器的根视图控制器。
下一步是将一个条形按钮项添加到View Controller的导航栏中,而不是“ Add Item View Controller” ,然后在Attributes Inspector中将其标识符设置为Add 。
当用户点击“ 添加”按钮时,应以模态显示 “ 添加项目视图控制器” 。 为此,请按Control键,然后从“ 添加”按钮拖到“ 导航控制器” , 然后从弹出菜单中选择“ 模态呈现 ”。 这将从“ 添加项目视图控制器”到新的“ 导航控制器”创建序列。
从对象库中拖动一个文本字段和一个按钮,并将它们添加到“ 添加项目视图控制器”场景中。 选择“ 添加项目视图控制器”,然后将textField
插座与文本字段连接,并将create(_:)
操作与按钮连接。 触发“ Touch Up Inside”事件时应触发create(_:)
操作。 将按钮的标题更改为Create并将必要的布局约束添加到文本字段和按钮。
要完成用户界面,请在“ 添加项目视图控制器 ”的导航栏的左上方添加一个条形按钮项目,并将其“ 标识符”设置为“ 取消” 。 选择添加项目视图控制器后 ,打开“ 连接”检查器并连接 cancel(_:)
动作到“ 取消”按钮。
通过按Command-R来验证并正确连接所有内容,从而生成并运行该应用程序。
2.实施委托协议
当用户点击“ 创建”按钮添加待办事项时,添加项视图控制器需要通知视图控制器。 对于这种情况,委托是一个完美的解决方案。 这个过程非常简单。
我们创建ViewController
类遵循的委托协议。 创建AddItemViewController
实例时(当用户点击“ 添加”按钮时), ViewController
对象被设置为AddItemViewController
实例的委托,使后者可以在创建新的待办事项时通知ViewController
实例。 让我们对其进行分解,以更好地了解此过程。
步骤1:声明AddItemViewControllerDelegate
协议
打开AddItemViewController.swift并在顶部import语句下方声明AddItemViewControllerDelegate
协议。 协议声明看起来类似于类声明。 protocol
关键字后跟协议名称。
import UIKit
protocol AddItemViewControllerDelegate {
func controller(_ controller: AddItemViewController, didAddItem: String)
}
该概念与Objective-C中的协议非常相似。 协议的名称为AddItemViewControllerDelegate ,它定义了一个方法controller(_:didAddItem:)
。
步骤2:声明delegate
属性
需要实现委托协议的对象是AddItemViewController
的委托。 我们首先需要为委托创建一个属性,如下面的代码片段所示。
class AddItemViewController: UIViewController {
@IBOutlet var textField: UITextField!
var delegate: AddItemViewControllerDelegate?
...
}
delegate
属性的类型为AddItemViewControllerDelegate?
,是一种可选类型,因为我们不能确定delegate
属性不是nil
。 请注意,协议的名称没有像在Objective-C中那样放在尖括号中。
步骤3:执行动作
委托方法controller(_:didAddItem:)
将在create(_:)
操作中调用,如下所示。 为了使示例简单,我们不对用户输入进行任何验证。
我们使用可选的链接来调用委托对象上的委托方法,这意味着只有在设置了delegate
属性的情况下才调用委托方法。 文本字段的值临时存储在常量item
。
@IBAction func create(_ sender: Any) {
if let item = textField.text {
delegate?.controller(self, didAddItem: item)
}
}
cancel(_:)
操作的实现很容易。 我们要做的就是关闭AddItemViewController
实例。
@IBAction func cancel(_ sender: Any) {
dismiss(animated: true)
}
步骤4:设定代表
不过,仍然缺少一个难题。 目前尚未设置AddItemViewController
实例的delegate
属性。 我们可以通过在ViewController
类中实现prepare(for:sender:)
方法来解决此问题。 但是,首先,我们需要重新审视情节提要。
打开Main.storyboard,然后选择将“ 添加”按钮与“ 导航控制器”连接起来的界面 。 打开“ 属性”检查器 ,并将segue的标识符设置为 AddItemViewController 。
接下来,在ViewController
类中实现prepare(for:sender:)
方法,如下所示。 注意,该方法的前缀是override
关键字。 现在应该已经很熟悉了。
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "AddItemViewController" {
let navigationController = segue.destination as? UINavigationController
let addItemViewController = navigationController?.topViewController as? AddItemViewController
if let viewController = addItemViewController {
viewController.delegate = self
}
}
}
我们首先检查序列号的标识符,确保准备正确的序列号。 然后,我们向segue询问其目标视图控制器。 您可能希望这是AddItemViewController
实例,但请记住,我们AddItemViewController
视图控制器设置为导航控制器的根视图控制器。 这意味着我们需要向导航控制器(segue的目的地视图控制器)请求其顶视图控制器。
addItemViewController
常量的类型为AddItemViewController?
因为使用了as?
关键词。 换句话说,通过使用as?
我们将topViewController
属性的值向下转换为可选类型。
在if
语句中,我们打开可选的包装并将delegate
属性设置为ViewController
实例。
我确定您已经注意到在prepare(for:sender:)
方法的实现中使用了几个可选参数。 与Objective-C API进行交互时,最好放心使用它。 虽然在Objective-C中将消息发送到nil
很好,但是在Swift中却不是。 由于存在这一关键差异,因此在Swift中与Objective-C API进行交互时,您始终需要格外小心。 上面的例子很好地说明了这一点。
步骤5:实施AddItemViewControllerDelegate
协议
实现AddItemViewControllerDelegate
协议类似于UITableViewDataSource
协议的实现。 我们首先使ViewController
类符合协议,如下所示。
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, AddItemViewControllerDelegate {
...
}
接下来,我们实现AddItemViewControllerDelegate
协议的方法,归结为实现controller(_:didAddItem:)
方法。 我们将新项目添加到视图控制器的items
属性中,重新加载表视图,并关闭添加项目视图控制器。
// MARK: Add Item View Controller Delegate Methods
func controller(_ controller: AddItemViewController, didAddItem: String) {
// Update Data Source
items.append(didAddItem)
// Reload Table View
tableView.reloadData()
// Dismiss Add Item View Controller
dismiss(animated: true)
}
步骤6:建立并执行
生成并运行该应用程序以测试是否可以将新项目添加到待办事项列表。 我们目前不验证用户的输入。 作为练习,如果用户点击“ 创建”按钮并且文本字段为空,则向用户显示警报视图。 添加空白待办事项不是很有用。 对?
结论
在本课程中,您学习了如何声明和实现自定义协议。 您还学习了如何创建动作并将其连接到Interface Builder中。 在下一课中,我们将通过添加删除待办事项的功能来完成待办事项应用程序,并且还将改善该应用程序的用户体验。
翻译自: https://code.tutsplus.com/tutorials/swift-from-scratch-delegation-and-properties--cms-23445