《Swift iOS应用开发实战》——2.5与代码进行关联

简介:

本节书摘来自华章计算机《Swift iOS应用开发实战》一书中的第2章,第2.5节,作者:刘铭 著, 更多章节内容可以访问云栖社区“华章计算机”公众号查看。

2.5与代码进行关联

通过前面的学习,我们已经知道如何在故事板中创建用户界面,但在搭建好用户界面以后又要做什么呢?接下来就需要将控件对象和程序代码关联起来。我们在创建Calculator项目的时候使用了默认的Single View Controller模板,该模板关联了故事板中的View Controller场景和ViewController.swift文件中的ViewController类。现在我们在故事板中查验一下。
在故事板中选中View Controller场景,使用Command+Option+3快捷键切换出标识检视窗(Identity Inspector),在Custom Class部分中,查看Class是否被设置为ViewController。

image

Class中所设置的ViewController指的就是项目中的View-Controller类(ViewController.swift文件中),ViewController类是一个控制器类,它包含一个View属性(指针),该属性指向故事板中的ViewController视图,也就是说ViewController类控制着这个视图。但是,这个控制器类还不能操作刚刚在这个视图中所添加的那些可视化控件,接下来就需要建立控制器和视图之间的关联。
2.5.1要完成的效果
本章的实践中,我们需要通过UIButton输入操作数和运算符,最后还要将计算结果显示到UILabel对象上,如图2-17所示。

image


2.5.2理解Outlet和Actions
在前面的实战练习中,我们使用Interface Builder设计了一个简单的计算器界面,并且还在Identifier检视窗中看到了所对应的ViewController.swift类。那么问题就是,我们通过什么方法能够让ViewController类中的代码与故事板中的用户界面元素进行交互呢?
方法肯定是有的,一个控制器类中的属性(实例变量)可以通过引用的方式与故事板或者nib文件中的视图对象建立联系,只要我们在类中声明属性的时候加上关键字IBOutlet。我们可以把Outlet想象成一个指向用户界面对象的指针。例如在Calculator项目中,我们创建了一个Label对象,当进行计算时,需要这个Label显示用户输入的数据以及计算的结果,所以通过Outlet就可以在代码中更新Label的显示内容。
与Outlet相反,当触发故事板或者nib文件中的界面对象时,需要执行指定类中的方法,这个指定的方法就是Action方法。例如Calculator项目中的数字按钮,当用户点击这些按钮的时候就要执行Action方法。我们甚至可以设置成当用户点击按钮以后执行某个方法,或者是当用户点击按钮后在手指离开的时候执行某个方法。
我们可以先在模拟器中查看用户界面的搭建效果。
步骤1点击Xcode工具栏中左侧的“Run”按钮,当编译成功以后,启动iOS模拟器并自动运行Calculator项目(设备建议选择iPhone 5或iPhone 5s)。此时,点击计算器中任何按钮的时候,只会看到按钮有被点击的效果反应,程序方面并不会执行什么。
当用户点击计算器按钮的时候,视图就会触发一个动作(Action),动作会以指定的方法形式呈现在ViewController类中。通过执行该方法,我们可以将运算结果反馈到故事板的Label中。所谓的反馈,实际上就是通过代码修改故事板中Label对象的属性,因此需要建立Outlet关联。
我们可以通过助手编辑器为ViewController类添加1个Outlet和17个Action。
在项目导航中选择Main.storyboard文件,从菜单中选择“View→Assistant Editor→ Show Assistant Editor”打开助手编辑器。
如果在故事板里面选中了某个视图场景,那么当我们打开助手编辑器后,会自动显示与场景对应的视图控制器类文件。比如,在当前Main.storyboard中选中的是ViewController场景,则切换到助手编辑器模式的时候,会自动打开ViewController.swift文件。如果没有打开该文件,则可以通过编辑器顶部的工具栏选择相应的文件,如图2-18所示。

image

接下来,我们开始创建ViewController类与故事板中Label的Outlet关联。
步骤2确定ViewController.swift文件显示在助手编辑窗口中。
步骤3故事板中,在Label控件上按住鼠标右键,将其拖曳至右侧窗口中ViewController.swift文件的@interface命令的下方,如图2-19所示。

image

松开鼠标以后会弹出关联设置面板,如图2-20所示。将Connection设置为Outlet,将Name设置为labelResult,Type和Storage不用修改,设置好后点击“Connect”按钮。

image

在Outlet关联构建好以后,ViewController类中会新增加一行@IBOutlet声明:

class ViewController: UIViewController {
                           
    @IBOutlet weak var labelResult: UILabel!
……

在这个例子中,我们创建了一个叫labelResult的Outlet,这个指针指向故事板中ViewController场景里面的Label对象。
在编译项目代码时,Swift编译器不会对@IBOutlet声明做任何特别的事情。@IBOutlet唯一的目的就是告诉Xcode这个属性会连接故事板或nib文件中的一个视图对象。也就是说,任何想要指向故事板或nib文件的属性必须被声明为@IBOutlet。
Action与Outlet正好相反,它代表一个动作,当用户在控件对象上进行交互操作并需要反馈给ViewController时,就会调用这个动作所关联的程序代码。当用户点击场景中按钮时,就会触发一个事件,这个事件会调用我们在类中定义的Action方法。
建立Action关联的方法与Outlet稍微有些区别,接下来我们为故事板中的UIButton与ViewController类建立Action关联。
步骤4在IBOutlet的下面添加5个实例变量的定义:

class ViewController: UIViewController {
    @IBOutlet weak var labelResult: UILabel!

    var firstOperand: Double = 0.0      // 第一操作数
    var secondOperand: Double  = 0.0    // 第二操作数
    var decimalPointFlag: Bool = false  // 标记是否输入了小数点
    var isSecond: Bool = false          // 是否输入第二操作数
    var operatorFlag: String = ""       // 操作符

步骤5故事板中,在按钮为0的Button控件上按住鼠标右键,然后将其拖曳至助手编辑器窗口中ViewController类中的didReceiveMemoryWarning方法的下面,如图2-21所示。
松开鼠标以后,在弹出的关联设置面板中,将Connection设置为Action,将Name设置为buttonTap,将Type设置为UIButton,将Event设置为Touch Up Inside,Arguments设置为Sender,如图2-22所示。设置好以后点击“Connect”按钮。

image

在默认情况下,关联设置面板中的Connection是Outlet,在选择Action以后面板会发生一些变化。Name代表所定义的Action方法的名称;Type代表该方法会携带一个参数,这个参数的类型是UIButton(传递给buttonTap方法的参数就是故事板中指向UIButton对象的指针变量),所以这里的Type我们设置为UIButton类型。Event代表用户所触发的事件,当用户点击按钮后并离开的时候会触发buttonTap方法;Arguments代表buttonTap方法所携带的参数形式,它分为3种:不带参数、带一个参数(Sender,表示用户在故事板中所交互的那个对象)、带两个参数(Sender和Event,除了所交互的视图对象外还有所触发的事件)。
在关联设置面板中点开Event列表后,会发现很多不同的事件,我们可以根据需要选择。
在创建好Action以后,ViewController.swift文件应该如下面这样:

import UIKit

class ViewController: UIViewController {
                            
    @IBOutlet weak var labelResult: UILabel!
    ……
    @IBAction func buttonTap(sender: UIButton) {
    }

}

步骤6以此类推,将1~9按钮与buttonTap方法建立IBAction关联。因为用户按0~9这10个按钮调用的都是buttonTap方法,所以我们不用为接下来的9个再单独创建新的方法。在1按钮上按住鼠标右键,拖曳至buttonTap方法上,如图2-23所示,再将2~9按钮照此方法操作。

image

步骤7在编辑器的右侧窗口中编辑ViewController.swift文件,找到buttonTap方法并在该方法中添加下面的代码:

@IBAction func buttonTap(sender: UIButton) {
         // labelResult中默认是0,如果开始输入数字,则先清除0
        if labelResult.text == "0" || (isSecond && secondOperand == 0.0) {
            labelResult.text = ""
        }
        // 将用户录入的数添加到labelResult中
        //labelResult.text = labelResult.text + sender.titleLabel
        if let value = sender.titleLabel?.text {
            labelResult.text = labelResult.text! + value
        }

        if isSecond {
            secondOperand = (labelResult.text! as NSString).doubleValue
        }else {
            // 将labelResult中的字符串转化为单精度数
            firstOperand = (labelResult.text! as NSString).doubleValue
        }
        
        // 在控制台中输出转换完的数值
        println(firstOperand)

构建并运行应用程序,当我们按下数字键以后,数值就会同时显示在Label和控制台中。接下来,我们还要处理有关小数点的问题。
步骤8将故事板中的小数点按钮与ViewController类建立IBAction关联。在小数点按钮上按住鼠标右键,拖曳至buttonTap方法的下面,在弹出的面板中Connection设置为Action,Name设置为decimalPointTap,Event设置为Touch Up Inside,Arguments设置为None。
通过IBAction关联,当我们点击小数点按钮以后,系统就会调用decimalPointTap方法,而且我们也不需要所传递的参数信息,所以将Arguments设置为None。
步骤9在ViewController.swift文件中添加下面关于小数点的程序代码:

class ViewController: UIViewController {
                            
    @IBOutlet weak var labelResult: UILabel!
    ……
    if isSecond {
                secondOperand = (labelResult.text! as NSString).doubleValue
            }else {
                firstOperand = (labelResult.text! as NSString).doubleValue
            }
            
            decimalPointFlag = !decimalPointFlag
        }
    }
}

构建并运行应用程序,此时可以正常输入带小数部分的数字。在第3章中我们还会继续完善Calculator项目,将添加更多的IBAction方法。
2.5.3使用快速检查器查看关联
如果我们在建立关联时出现了错误,比如关联了错误的Outlet变量,为错误的事件指定了一个Action方法等。要想查看某场景所有的关联信息,可以在故事板大纲视图的ViewController图标上点击鼠标右键调出快速检查器,如图2-24所示。

image

在快速检查器中,我们可以点击已关联好的对象前面的“X”移除关联,也可以点击后面的圆圈建立新的关联。点击检查器左上角的“X”可以关闭整个快速检查器。
除了通过快速检查器检查关联以外,在代码文件中也可以查看是否成功关联。
1)在项目导航中选择ViewController.swift文件。
2)在IBOutlet和IBAction的声明语句之前看到实心的圆点,代表已经成功建立关联,如图4-31所示。如果看到的是空心圆点,则代表没有建立关联。

image

在故事板中成功建立关联以后,如果此时想要在代码中删除Outlet变量或Action方法,还需要在故事板中删除建立的关联,否则会导致程序崩溃退出。

相关文章
|
1月前
|
设计模式 安全 Swift
探索iOS开发:打造你的第一个天气应用
【9月更文挑战第36天】在这篇文章中,我们将一起踏上iOS开发的旅程,从零开始构建一个简单的天气应用。文章将通过通俗易懂的语言,引导你理解iOS开发的基本概念,掌握Swift语言的核心语法,并逐步实现一个具有实际功能的天气应用。我们将遵循“学中做,做中学”的原则,让理论知识和实践操作紧密结合,确保学习过程既高效又有趣。无论你是编程新手还是希望拓展技能的开发者,这篇文章都将为你打开一扇通往iOS开发世界的大门。
|
1月前
|
搜索推荐 IDE API
打造个性化天气应用:iOS开发之旅
【9月更文挑战第35天】在这篇文章中,我们将一起踏上iOS开发的旅程,通过创建一个个性化的天气应用来探索Swift编程语言的魅力和iOS平台的强大功能。无论你是编程新手还是希望扩展你的技能集,这个项目都将为你提供实战经验,帮助你理解从构思到实现一个应用的全过程。让我们开始吧,构建你自己的天气应用,探索更多可能!
63 1
|
7天前
|
安全 数据处理 Swift
深入探索iOS开发中的Swift语言特性
本文旨在为开发者提供对Swift语言在iOS平台开发的深度理解,涵盖从基础语法到高级特性的全面分析。通过具体案例和代码示例,揭示Swift如何简化编程过程、提高代码效率,并促进iOS应用的创新。文章不仅适合初学者作为入门指南,也适合有经验的开发者深化对Swift语言的认识。
25 9
|
5天前
|
机器学习/深度学习 安全 数据挖掘
Swift语言的应用场景非常广泛
Swift语言的应用场景非常广泛
16 4
|
8天前
|
JSON 前端开发 API
探索iOS开发之旅:打造你的第一个天气应用
【10月更文挑战第36天】在这篇文章中,我们将踏上一段激动人心的旅程,一起构建属于我们自己的iOS天气应用。通过这个实战项目,你将学习到如何从零开始搭建一个iOS应用,掌握基本的用户界面设计、网络请求处理以及数据解析等核心技能。无论你是编程新手还是希望扩展你的iOS开发技能,这个项目都将为你提供宝贵的实践经验。准备好了吗?让我们开始吧!
|
17天前
|
Swift iOS开发 UED
如何使用Swift和UIKit在iOS应用中实现自定义按钮动画
本文通过一个具体案例,介绍如何使用Swift和UIKit在iOS应用中实现自定义按钮动画。当用户点击按钮时,按钮将从圆形变为椭圆形,颜色从蓝色渐变到绿色;释放按钮时,动画以相反方式恢复。通过UIView的动画方法和弹簧动画效果,实现平滑自然的过渡。
32 1
|
21天前
|
安全 API Swift
探索iOS开发中的Swift语言之美
【10月更文挑战第23天】在数字时代的浪潮中,iOS开发如同一艘航船,而Swift语言则是推动这艘船前进的风帆。本文将带你领略Swift的独特魅力,从语法到设计哲学,再到实际应用案例,我们将一步步深入这个现代编程语言的世界。你将发现,Swift不仅仅是一种编程语言,它是苹果生态系统中的一个创新工具,它让iOS开发变得更加高效、安全和有趣。让我们一起启航,探索Swift的奥秘,感受编程的乐趣。
|
26天前
|
Swift iOS开发 UED
如何使用Swift和UIKit在iOS应用中实现自定义按钮动画
【10月更文挑战第18天】本文通过一个具体案例,介绍如何使用Swift和UIKit在iOS应用中实现自定义按钮动画。当用户按下按钮时,按钮将从圆形变为椭圆形并从蓝色渐变为绿色;释放按钮时,动画恢复原状。通过UIView的动画方法和弹簧动画效果,实现平滑自然的动画过渡。
47 5
|
1月前
|
Android开发 Swift iOS开发
探索安卓与iOS开发的差异:从代码到用户体验
【10月更文挑战第5天】在移动应用开发的广阔天地中,安卓和iOS两大平台各占半壁江山。它们在技术架构、开发环境及用户体验上有着根本的不同。本文通过比较这两种平台的开发过程,揭示背后的设计理念和技术选择如何影响最终产品。我们将深入探讨各自平台的代码示例,理解开发者面临的挑战,以及这些差异如何塑造用户的日常体验。
|
1月前
|
安全 Swift iOS开发
探索iOS开发中的Swift语言之美
在数字时代的浪潮中,移动应用已成为日常生活的延伸。本文将深入探讨iOS平台上的Swift编程语言,揭示其背后的设计哲学、语法特性以及如何利用Swift进行高效开发。我们将通过实际代码示例,展示Swift语言的强大功能和优雅简洁的编程风格,引导读者理解并运用Swift解决实际问题。