Swift官方入门教程系列--二--storyboard与代码的交互【翻译版,源代码】

来源:互联网 发布:人工智能 伏羲觉醒结局 编辑:程序博客网 时间:2024/05/17 08:45


代码详见github:02_storyboard交互代码


在本课中,将会学习storyboard与代码的交互完成后,您的应用程序将如下所示:

image:../Art/CUIC_sim_finalUI_2x.png

学习目标

在课程结束时,您将能够:

  • 解释故事板中的场景与底层视图控制器之间的关系

  • 在故事板中的UI元素和源代码之间创建插座和动作连接

  • 从文本字段处理用户输入,并在UI中显示结果

  • 使类符合协议

  • 了解授权模式

  • 在设计应用程序架构时,请遵循目标操作模式

  • 源码

将UI连接到源代码

在元素的故事板链接到源代码。重要的是要了解故事板与您编写的代码之间的关系。

在故事板,一个现场代表的内容一屏,通常一个视图控制器。视图控制器实现你的应用程序的行为。视图控制器管理具有其子视图层次结构的单个内容视图。视图控制器的坐标信息的应用程序的之间的流动数据模型,它封装应用程序的数据,并且显示的数据,管理他们的内容的看法生命周期的看法,处理方向变化时,该设备旋转时,定义内的导航您的应用程序,并实现行为以响应用户输入。在iOS中所有视图控制器对象类型UIViewController或它的一个子类。

你可以通过创建和实现自定义视图控制器在代码中定义的视图控制器的行为的子类然后,您可以在故事板中的这些类和场景之间创建连接,以获取在代码中定义的行为以及您在故事板中定义的用户界面。

Xcode中已经创建,你看前面,其中一类ViewController.swift,它连接到你现在在你的故事板的工作现场。将来,当您添加更多场景时,您将在Identity检查器中自行创建此连接。身份检查可以让你在故事板涉及到该对象的身份,比如什么类的对象属于编辑对象的属性。

image:../Art/CUIC_inspector_identity_2x.png

在运行时,你的故事板创建的实例ViewController,您的自定义视图控制器子类。从你的故事板的场景出现在设备的屏幕上,用户界面的行为定义ViewController.swift

虽然现场被连接到ViewController.swift,这不是一个需要进行的唯一的连接。要在应用程序中定义交互,您的视图控制器源代码需要能够与故事板中的视图进行通信。您可以通过在故事板中的视图和视图控制器源代码文件之间定义额外的连接(称为插座和操作)来实现。

创建UI元素的Outlet

奥特莱斯提供了一种方法来引用接口的对象,您将添加到您的故事板,从源代码文件的对象。要创建插座,请将控件从故事板中的特定对象拖动到视图控制器文件。此操作创建一个属性在您的视图控制器文件的对象,它可以让你访问和操纵从代码对象在运行时。

您需要为用户界面中的文本字段和标签创建插座,以便能够引用它们。

将文本字段连接到ViewController.swift代码

  1. 打开你的故事板,Main.storyboard

  2. 点击助手按钮Xcode的工具栏附近的Xcode的右上角打开助理编辑

    image:../Art/assistant_editor_toggle_2x.png
  3. 如果您想了解更多的工作空间,折叠项目导航生活区通过点击工具栏中的Xcode在导航和实用程序的按钮。

    image:../Art/navigator_utilities_toggle_on_2x.png

    您也可以折叠大纲视图

  4. 在编辑器中选择栏,它出现在助理编辑器的顶部,从预览的助理编辑>更改为自动ViewController.swift

    image:../Art/CUIC_switchtoviewcontroller_2x.png

    ViewController.swift 显示在右侧的编辑器中。

  5. ViewController.swift中,找到class行,应该是这样的:

    1. classViewController:UIViewController {
  6. 下面的class线,添加以下内容:

    1. //MARK: Properties

    您刚刚向源代码添加了注释。回想一下,一个评论是在不被编译在程序的一部分,但提供上下文或有关的代码的各个部分有用信息的源代码文件中的一段文字。

    以字符开头的注释//MARK:是所使用的组织代码,并帮助你(和其他人谁读你的代码)通过它浏览评论的一种特殊类型。你稍后会看到这个动作。具体来说,您添加的评论表明,这是您的代码列出属性的部分。

  7. 在您的故事板中,选择文本字段。

  8. 从文本字段按住Control键拖动您的画布在右边的编辑器的代码显示,停在你刚刚添加的注释下就行了阻力ViewController.swift

    image:../Art/CUIC_textfield_dragoutlet_2x.png
  9. 在出现的名称,类型对话框nameTextField

    保留其余的选项。您的对话框应如下所示:

    image:../Art/CUIC_textfield_addoutlet_2x.png
  10. 单击连接。

    Xcode中添加必要的代码ViewController.swift来存储文本字段的引用和配置故事板来设置该连接。

    1. @IBOutletweakvarnameTextField:UITextField!

花一点时间了解这行代码中发生了什么。

IBOutlet属性告诉Xcode中,你可以连接到nameTextField从Interface Builder的财产(这就是为什么属性具有IB前缀)。weak关键字表示该参考文献没有阻止系统解除分配被引用对象。弱参考有助于防止参考周期; 然而,要保持对象活着和在内存中,你需要确保你的应用程序的一些其他部分有一个强的引用对象。在这种情况下,它是文本字段的superview。超级视图对所有子视图都有强大的引用。只要superview仍然活着和在内存中,所有的subviews仍然活着。类似地,视图控制器具有对其内容视图的强参考 - 保持整个视图层次结构活着和在存储器中。

声明的其余部分定义了一个隐含解开可选类型的变量UITextField命名nameTextField请注意类型声明末尾的感叹号。这个感叹号表明该类型是隐式展开可选的,这是一个可选的类型,将永远有一个值后,这是第一套。当您访问隐式解包的可选,系统假定它有一个有效的值,并自动解开它。请注意,如果变量的值尚未设置,这将导致应用程序终止。

当从故事板加载视图控制器时,系统实例化视图层次结构并向所有视图控制器的出口分配适当的值。由视图控制器的时间viewDidLoad()方法被调用时,该系统已分配有效值所有控制器的网点,您可以安全地访问他们的内容。

现在,以与连接文本字段相同的方式将标签连接到代码。

将标签连接到ViewController.swift代码

  1. 在您的故事板中,选择标签。

  2. 从画布到右边的编辑器中的代码显示在标签控件拖动,停在该行正下方的阻力nameTextField财产ViewController.swift

    image:../Art/CUIC_label_dragoutlet_2x.png
  3. 在出现的名称,类型对话框mealNameLabel

    保留其余的选项。您的对话框应如下所示:

    image:../Art/CUIC_label_addoutlet_2x.png
  4. 单击连接。

再次,Xcode中添加必要的代码ViewController.swift来存储到标签的引用,并配置故事板来设置该连接。该出口是类似文本字段,除了它的名字和它的类型(是UILabel,以匹配公司在故事板对象的类型)。

  1. @IBOutletweakvarmealNameLabel:UILabel!

如果您计划从接口对象访问值或修改代码中的接口对象,则只需要一个接口对象的插口。在这种情况下,你需要设置文本字段的delegate属性,然后设置标签的text属性。你不会修改按钮,所以没有理由为它创建一个插座。

出口允许您在代码中引用您的界面元素,但是您仍然需要一种方法来在用户与元素进行交互时进行响应。这就是行动进来的地方。

定义要执行的操作

iOS应用程序是基于事件驱动编程也就是说,应用程序的流程由事件:系统事件和用户操作决定。用户在触发应用程序中的事件的界面中执行操作。这些事件导致应用程序逻辑的执行和数据的操作。应用程序对用户操作的响应然后反映在用户界面中。由于用户而不是开发人员可以控制应用程序代码的某些部分何时得到执行,因此您需要确定用户可以执行哪些操作以及响应这些操作会发生什么。

一个动作(或动作方法)是一段代码的链接到可以发生在你的应用程序的事件。当该事件发生时,系统执行动作的代码。您可以定义操作方法来完成从操作数据到更新用户界面等操作。您可以使用操作来响应用户或系统事件来驱动应用程序的流程。

您创建操作的方式与创建插座相同:控制 - 从故事板中的特定对象拖动到视图控制器文件。此操作在视图控制器文件中创建一个方法,该方法在用户与动作方法所附加的对象交互时被触发。

通过创建一个简单的动作,设置标签开始Default Text,每当用户点击设置默认文本按钮。(设置标签的文本字段的代码是更复杂一点,所以你会写,在处理用户输入的部分。)

在ViewController.swift代码中创建setDefaultLabelText操作

  1. ViewController.swift正上方的最后一个大括号(}),添加以下内容:

    1. //MARK: Actions

    此评论表示这是列出操作的代码部分。

  2. 在您的故事板中,选择设置默认标签文本按钮。

  3. 从画布到右边的编辑器中的代码显示设置默认标签文本按钮控件拖拽,停在你刚刚添加的注释下就行了阻力ViewController.swift

    image:../Art/CUIC_button_dragaction_2x.png
  4. 在出现的对话框中,对于连接,选择操作。

  5. 对于名称,键入setDefaultLabelText

  6. 对于类型,请选择UIButton

    您可能已经注意到,该类型字段默认值AnyObject在夫特,AnyObject是用于描述可以属于任何类的对象的类型。指定该操作方法是类型UIButton意味着,唯一的按钮对象可以连接到这个动作。虽然这对您现在创建的操作不重要,但请务必记住以后。

    保留其余的选项。您的对话框应如下所示:

    image:../Art/CUIC_button_addaction_2x.png
  7. 单击连接。

Xcode中添加必要的代码ViewController.swift来设置操作方法。

  1. @IBActionfuncsetDefaultLabelText(_sender:UIButton) {
  2. }

sender参数是指负责触发动作在这种情况下,一个按钮的对象。IBAction属性表明,该方法是,你可以在Interface Builder的故事板连接到一个动作。声明的其余部分通过声明的名称的方法setDefaultLabelText(_:)

现在,方法声明为空。重置标签值的代码非常简单。

在ViewController代码中实现标签重置操作

  1. ViewController.swift中,找到setDefaultLabelText刚才添加的操作方法。

  2. 在该方法的实现,大括号(之间{}),加上这行代码:

    1. mealNameLabel.text = "Default Text"

    正如你可能已经猜到,这个代码设置标签的text属性为默认文本。

    请注意,你没有指定默认文本的类型,因为斯威夫特的类型推断可以看到你分配给类型的东西String,并能正确推断类型。

iOS处理所有的重绘代码,所以这实际上是你现在需要写的所有代码。您的setDefaultLabelText(_:)操作方法应该是这样的:

  1. @IBActionfuncsetDefaultLabelText(_sender:UIButton) {
  2. mealNameLabel.text = "Default Text"
  3. }

检查点:通过运行模拟器来测试您的更改。当您单击设置默认标签文本按钮,你的setDefaultLabelText(_:)方法被调用,而mealNameLabel对象的text距离值的变化Meal Name来(在你的故事板设置的值)Default Text(操作设定的值)。您应该会在您的用户界面中看到更改。

image:../Art/CUIC_sim_defaulttext_2x.png

将膳食的名称更改为“默认文本”不是特别有用,它确实说明了一个重要的点。你只是执行的行为的一个例子目标-动作在iOS应用设计模式。目标动作是一种设计模式,其中当特定事件发生时,一个对象将消息发送到另一个对象。

在这种情况下:

  • 该事件是用户点击设置默认文本按钮。

  • 动作setDefaultLabelText(_)

  • 我们的目标是ViewController(action方法定义的地方)。

  • 发件人是设置默认标签文本按钮。

系统通过调用目标上的action方法并传递sender对象来发送消息。发送者通常是诸如按钮,滑块或开关之类的控件,其可以响应于用户交互(例如轻敲,拖动或值改变)来触发事件。这种模式在iOS应用程序编程中非常常见,在整个课程中你会看到更多。

处理用户输入

此时,用户可以将膳食名称标签重置为默认值,但是您真的想让用户使用文本字段输入自己的膳食名称。为了简单起见,你会更新mealNameLabel对象text,每当用户输入到文本字段,水龙头返回值。

当您从文本字段接受用户输入时,您需要从文本字段委派中获得一些帮助。一个代表是行为代表的,或与其他对象协调的对象。委托对象(在这种情况下是文本字段)保留对其他对象(委托)的引用,并且在适当的时间,委托对象向委托发送消息。该消息告诉委托者委托对象将要处理或刚刚处理的事件。代理可以通过例如更新其自身或者应用中的其他对象的外观或状态,或者返回影响如何处理即将发生的事件的值来作出响应。

文本字段的代理在用户编辑文本时与文本字段通信,并且知道重要事件何时发生 - 例如当用户开始或停止编辑文本时。代理可以使用此信息在正确的时间保存或清除数据,关闭键盘等。

只要任何对象都可以作为一个委托另一个目的,因为它符合到适当的协议它定义了一个文本字段的委托协议被称为UITextFieldDelegate将视图控制器作为其管理的对象的委托是非常常见的。在这种情况下,你会让你的ViewController实例中的文本字段的委托。

首先,ViewController需要采用的UITextFieldDelegate协议。采用通过将其列为类声明线的一部分的协议。

采用UITextFieldDelegate协议

  1. 如果辅助编辑器打开,请通过单击标准按钮返回到标准编辑器。

    image:../Art/standard_toggle_2x.png
  2. 通过单击Xco​​de工具栏中的导航器和实用程序按钮,展开项目导航器和实用程序区域。

  3. 在项目导航栏中选择ViewController.swift

  4. ViewController.swift中,找到class行,应该是这样的:

    1. classViewController:UIViewController {
  5. 之后UIViewController,添加一个逗号(,),并UITextFieldDelegate通过该协议。

    1. classViewController:UIViewController,UITextFieldDelegate {

通过采用该UITextFieldDelegate协议,你告诉了编译器ViewController类可以作为一个有效的文本字段代表行事。这意味着你可以实现协议的方法来处理文字输入,并且可以分配的实例ViewController类作为文本字段的委托。

将ViewController对象设置为其nameTextField属性的委托

  1. ViewController.swift中,找到viewDidLoad()方法,它应该是这样的:

    1. overridefuncviewDidLoad() {
    2. super.viewDidLoad()
    3. // Do any additional setup after loading the view, typically from a nib.
    4. }

    此方法的模板实现包括注释。您在方法实现中不需要此注释,因此请继续并删除它。

  2. 下面的super.viewDidLoad()行中,添加一个空行及以下:

    1. // Handle the text field’s user input through delegate callbacks.
    2. nameTextField.delegate = self

    selfViewController类,因为它的范围内引用的ViewController类定义。

    您可以添加自己的评论,以帮助您了解代码中发生了什么。

你的viewDidLoad()方法应该是这样的:

  1. overridefuncviewDidLoad() {
  2. super.viewDidLoad()
  3. // Handle the text field’s user input through delegate callbacks.
  4. nameTextField.delegate = self
  5. }

当一个ViewController实例被加载时,它本身设置作为其委托nameTextField财产。

UITextFieldDelegate协议定义了8个可选的方法。只是实现你需要的,以获得你想要的行为。现在,您需要实现以下两种方法:

  1. functextFieldShouldReturn(_textField:UITextField) -> Bool
  2. functextFieldDidEndEditing(_textField:UITextField)

要理解这些方法何时被调用以及需要做什么,知道文本字段如何响应用户事件很重要。当用户点击文本字段时,它将自动成为第一个响应者。在一个应用程序中,第一响应者是一个对象,它是第一个用于接收多种应用程序的事件,包括关键事件,移动事件,并采取行动的信息,其中包括该行。换句话说,由用户产生的许多事件最初被路由到第一响应者。

由于文本字段成为第一个响应者,iOS会显示键盘,并为该文本字段开始编辑会话。用户使用该键盘键入的内容将插入到文本字段中。

当用户想要完成文本字段的编辑时,文本字段需要辞去其第一响应者状态。因为文本字段将不再是应用程序中的活动对象,所以事件需要路由到更合适的对象。

这是你的执行UITextFieldDelegate方法进来,你需要指定,当用户点击一个按钮,结束在文本字段编辑文本字段应该辞职的第一响应状态。你在做这个textFieldShouldReturn(_:)方法中,当用户敲击回车键盘上被调用(或在这种情况下,完成)。

实现UITextFieldDelegate协议方法textFieldShouldReturn(_ :)

  1. ViewController.swift,正上方的//MARK: Actions部分,添加以下内容:

    1. //MARK: UITextFieldDelegate

    此评论用于组织您的代码,并帮助您(和任何读取您的代码的人)浏览它。

    您已经添加了这些评论到目前为止。Xcode中列出这些意见作为源代码文件的一个部分标题的功能菜单中,如果您单击编辑器区域顶部的文件的名称出现。函数菜单允许您快速跳转到代码中的某个部分。你会发现你所表示的部分//MARK:在这里列出。您可以单击其中一个节标题,跳转到文件中的该节。

    image:../Art/CUIC_functionsmenu_2x.png
  2. 在注释下面,添加以下方法:

    1. functextFieldShouldReturn(_textField:UITextField) -> Bool {
    2. }
  3. 在此方法中,添加以下代码以辞职文本字段的第一响应者状态,并添加注释以描述代码执行的操作:

    1. // Hide the keyboard.
    2. textField.resignFirstResponder()

    尝试输入第二行,而不是仅仅复制和粘贴。你会发现,代码完成是Xcode中的巨大节省时间的特点之一。当Xcode显示潜在完成列表时,滚动列表,直到找到所需的列表,然后按Return键。Xcode为你插入整行。

    image:../Art/CUIC_code_completion_2x.png
  4. 在这种方法中,添加以下代码行:

    1. returntrue

    此方法返回一个布尔值,指示系统是否应处理按Return键。在这种情况下,你总是希望响应用户按下回车键,所以才返回true

你的textFieldShouldReturn(_:)方法应该是这样的:

  1. functextFieldShouldReturn(_textField:UITextField) -> Bool {
  2. // Hide the keyboard.
  3. textField.resignFirstResponder()
  4. returntrue
  5. }

你需要实现第二个方法textFieldDidEndEditing(_:),是文本字段辞职的第一响应状态后调用。因为你辞职第一响应状态textFieldShouldReturn时,系统只调用后调用此方法textFieldShouldReturn

textFieldDidEndEditing(_:)方法给你一个机会阅读输入到文本字段中的信息,并用它做什么。在您的情况下,您将获取文本字段中的文本,并使用它来更改标签的值。

实现UITextFieldDelegate协议方法textFieldDidEndEditing(_ :)

  1. ViewController.swift中,后textFieldShouldReturn(_:)的方法,添加下面的方法:

    1. functextFieldDidEndEditing(_textField:UITextField) {
    2. }
  2. 在这种方法中,添加以下代码行:

    1. mealNameLabel.text = textField.text

这就是你需要做的,看看的结果。你的textFieldDidEndEditing(_:)方法应该是这样的:

  1. functextFieldDidEndEditing(_textField:UITextField) {
  2. mealNameLabel.text = textField.text
  3. }

检查点:通过运行模拟器来测试您的更改。您可以选择文本字段并在其中键入文本。当您单击键盘上的完成按钮时,将关闭键盘,并更改标签文本以在文本字段中显示文本。当您单击设置默认标签文本按钮,从什么当前显示的标签,该标签的变化Default Text(由先前定义的动作设置的值)。

image:../Art/CUIC_sim_finalUI_2x.png


代码详见github:02_storyboard交互代码

0 0
原创粉丝点击