第三章练习Tip Calculator - 编写一个小费计算器App吧

练习:Tip Calculator 小费计算器

下一个App可以帮助用户计算他们每次去餐厅吃饭时应该付多少钱给服务员吗,用户输入总消费额,然后从3个费率:15%,20%和25%中挑一个费率,用户点击计算按钮,消费数额就会出现在屏幕上。App完成版本的效果图如下(见图3-5):

Exercise: Tip Calculator | Page 71

现在你知道了App有哪些功能,那么打开Xcode吧,点击Dock中的Xcode图标,如果Dock中没有Xcode,那么去Spotlight中搜索一下。

接着会出现熟悉的Xcode欢迎界面。关闭欢迎界面,点击顶部菜单栏的File -> New -> Project(见图3-6)。

Page 72 | Chapter 3 : Diving into Swift

从模板中选择Single View Application,点击Next(见图3-7)。

Project的一些项目可能已经自动为你填写好了。

Exercise: Tip Calculator | Page 73

在Product Name一栏输入TipCalcualtor,Organization Name和Organization Identifier可以写成你的姓名,之间不要有空格。最后,Language选择Swift,Devices选择iPhone,点击Next(见图3-8)。

接下来从左侧选择你要存放的文件夹,点击Create,保存工程(见图3-9)。

Page 74 | Chapter 3 : Diving into Swift

出现了工程的详细信息界面(见图3-10)。

Exercise: Tip Calculator | Page 75

点击Project Navigator中的Main.storyboard文件(见图3-11)。

我们这次开发的App仅限于在iPhone上使用,点击Inspector的上方第一个按钮,看起来像是一张纸折了一个角。到中间部分,不勾选Use Auto Layout选项。这时会出现一个对话框,选择iPhone。然后不勾选Disable Size Classes(见图3-12)。这时,Storyboard中的界面形状会改变。我们将会在第七章详细介绍Auto Layout的知识。

Page 76 | Chapter 3 : Diving into Swift

确保Inspector在屏幕的右方。如果没有出现在屏幕右方,点击Inspector View Button,就是右上角右边有一条条纹的按钮,这样就可以显示Inspector了。

Inspector下方有个小的工具栏按钮,Object Library图标(圆圈中有个小方块)在图3-13中蓝色高亮了,如果你的Xcode这个图标不是蓝色,点击一下这个图标。

Exercise: Tip Calculator | Page 77

Object Library的下方有个搜索框,输入Label(见图3-14),Object Library搜索框能够方便地找到我们需要的控件。在使用完毕后记得情况输入框中的文字,不然你就看不到所有的控件了。

将一个Label控件拖入到界面中(见图3-15)。借助辅助线让Label水平居中且垂直居中。

Page 78 | Chapter 3 : Diving into Swift

看一下Inspector顶部的工具栏按钮,点击Attribute Inspector图标,从左数第四个(见图3-16),看起来像是一个朝下的箭头。

在text属性中输入为$0.00,点击回车。然后点击center alignment按钮(见图3-17)。

再回到Inspector上方的工具栏,点击从右往左第二个外表像是尺子的图标来打开Size Inspector(见图3-18)。Size Inspector可以设置控件具体位置。

Exercise: Tip Calculator | Page 79

宽设置为100,X值设置为110,Y值设置为200,这时注意界面中Label的位置已经发生了变化(见图3-19)。点击Attribute Inspector图标。

Page 80 | Chapter 3 : Diving into Swift

接下来,我们要往界面上放一个Button。把鼠标光标移动到右下角,在Object Library找到Button控件(见图3-20),把Button控件拖动到界面上。借助辅助线让Button水平居中,放在Label的上方(见图3-21)。

双击Button,输入Calculate,回车。

Exercise: Tip Calculator | Page 81

接下来我们要添加一个Segmented Control(见图3-22)。Segmented Control有点像是switch不过有更多选择。Segmented Control可以在两个或者更多的segments之前点击切换,一次只能选择一个segment。

在Object Library中找到Segmented Control,然后拖到界面上,把Segmented Control放到Button的上方(见图3-23)。

Page 82 | Chapter 3 : Diving into Swift

选中Segmented Control,然后点击Inspector上的Attribute Inspector,把Segments的数字修改为3(见图3-24)。你会看到界面上的Segmented Control已经变成了3个(见图3-25)。

接着双击Segmented Control上的First单词,修改为15%,回车。双击Second修改为20%,双击第三个Segment,输入25%(见图3-26)。

Exercise: Tip Calculator | Page 83

最后需要添加的控件是Text Field,Text Field可以让用户通过敲击键盘输入东西。

到Object Library中找到Text Field(见图3-27)。把Text Field拖到界面上,放到Segmented Control的上方(见图3-28)。

Page 84 | Chapter 3 : Diving into Swift

点击Attribute Inspector,找到Placeholder属性,从上往下第五行。输入Total Bill $(见图3-29)。placeholder的文案有点像是向导,指导你在Text Field中输入什么文字。

当用户点击Text Field时,placeholder中的文字会消失不见,然后键盘出现在屏幕上。

Exercise: Tip Calculator | Page 85

接下来在Inspector中找到Keyboard Type属性,点击Default右边下拉按钮,选择Decimal Pad(见图3-30)。这样,弹出的键盘就只有数字了,用户不需要在这里输入字母。

现在界面已经搭建完毕了,那么接下来需要我们把界面view和conroller(就是swift文件)连起来了。和上一章节中的练习一样,我们会用到Assistant Editor,来连接view和controller。

在屏幕的右上角,点击Assistant Editor按钮(见图3-31)。打开Assistant Editor后,点击Inspector View按钮,让Editor的空间更大一些(见图3-32)。

Page 86 | Chapter 3 : Diving into Swift

Assistant Editor会自动打开ViewController.swift文件,Assistant Editor上方在“Automatic”右边会有文件名称,核对一下是否是ViewController.swift。

选中界面上的Text Field控件,同时按住Control键,将Text Field控件拖到右边ViewController.swift文件中下面这行代码的下方:

class ViewController: UIViewController {

当你看到一条蓝色的横线时,然后松开鼠标(见图3-33),接着出现一个弹出框(见图3-34)。

Exercise: Tip Calculator | Page 87

因为你要获取Text Field中用户输入的数值,所以我们使用Outlet连接类型。在Name一栏中输入billTextField作为变量名,其余不变,点击Connect完成连接。

当你点击Connect后会产生一行代码(见图3-35)。看一下这行代码:

@IBOutlet var billTextField : UITextField!

Page 88 | Chapter 3 : Diving into Swift

我们先跳过第一个单词,过会再来讨论它。先看一下var这个单词,var用来声明变量,billTextField是这个变量的名字,冒号用来声明这个变量的类型,UITextField就是这个变量的类型。最后,@IBOutlet这个次用来表示这是view和controller之间的一个outlet连接。billTextField这个变量在代码就代表界面上的这个Text Field控件。

选中Segmented Control控件,同时按住Control键,然后拖到右边ViewController.swift文件中下面这行代码的下方:

class ViewController: UIViewController {

当你看到一条蓝色的横线时,然后松开鼠标(见图3-36),接着出现一个弹出框(见图3-37)。

Exercise: Tip Calculator | Page 89

将Connection设置为Outlet,Name是tipRateSegmentedControl。剩下的选项不变,然后点击Connect。

接下来选中界面上的Label控件,同时按住Control键,然后拖到右边ViewController.swift文件中下面这行代码的下方:

class ViewController: UIViewController {

当你看到一条蓝色的横线时,然后松开鼠标(见图3-38),接着出现一个弹出框(见图3-39)。

Page 90 | Chapter 3 : Diving into Swift

将Connection设置为Outlet,Name是tipLabel,剩下的选项不变,然后点击Connect。

最后,选中界面上的Button控件,同时按住Control键,然后拖到右边ViewController.swift文件中下面这行代码的下方:

class ViewController: UIViewController {

当你看到一条蓝色的横线时,然后松开鼠标(见图3-40),接着出现一个弹出框(见图3-41)。

Exercise: Tip Calculator | Page 91

将Connection设置为Action,Name是calculateTapped。剩下的选项不变,然后点击Connect。

你添加到ViewController.swift中的代码会是下面这个样子:

@IBOutlet var tipLabel : UILabel!
@IBOutlet var tipRateSegmentedControl : UISegmentedControl!
@IBOutlet var billTextField : UITextField!

@IBAction func calculateTapped(sender : AnyObject) {

}

Page 92 | Chapter 3 : Diving into Swift

calculateTapped action会自动添加一个方法,每次用户点击Button时,这个方法都会被调用。把你的鼠标光标放到这个方法的两个大括号之间。

按照最佳实践原则,我们需要写注释,说明你在接下来的代码中将要完成哪些事情。这个过程,就做pseudocoding(伪代码),能够让你在写一个方法之前有一个大概的轮廓。你可以直接在Xcode中写注释,注释还可以帮助其他程序员看懂你的代码。当运行App或者编译代码时,我们是看不到注释的。

前面先写两个斜杠,后面的文字就是注释了。例如:

@IBAction func calculateTapped(sender : AnyObject) {
    //This code is run each time the Calculate Button is tapped.

}

在calculateTapped方法中添加下面的注释:

@IBAction func calculateTapped(sender : AnyObject) {
    //1\. 获取账单的总金额
    //2\. 确定小费费率
    //3\. 计算小费金额
    //4\. 将消费金额呈现给用户

}

接下来,需要确定费率:15%,20%或25%。确定下费率后,总金额乘以费率,就是小费金额,然后将消费金额呈现给用户。

现在你已经给方法大体规划了计划,那么我们需要为每一步编写代码了。

想要获得总金额,使用要使用Text Field控件变量billTextField的text属性。把鼠标光标放到第一行注释的后面,按回车。接着输入下面的代码:

Introducing IOS 8
var userInput = billTextField.text as NSString

(注意,作者写这本书的时候swift2.0还没有出来,现在NSString和String合二为一了,苹果官方推荐使用String,不再推荐使用NSString了)

你可以注意到了,在你输入代码的时候,Xcode会提供一些单词来帮助你写代码,例如,从billTextField中删除“.text”,然后只输入“.”。

这种预测输入系统叫做Autocomplete(自动补全)。自动补全极大的提高了开发者的体验,自动补全弹出框会显示此变量所有可用的属性和方法。

Exercise: Tip Calculator | Page 93

在billTextField.后面在输入te两个字母,自动补全就会更新可用属性,甚至会显示text属性返回一个字符串,点击Tab键接受自动补全。

现在你已经获取了Text Field控件中的text,然而,text是一个字符串格式,不是数值,无法进行数学计算,我们需要把text的字符串类型转换为Float类型。Float是带有小数点的数字,Float类型特别适合处理货币计算。转换类型的代码如下:

var totalBill: Float = userInput.floatValue

这行代码创建了一个新的变量totalBill,然后设置类型为float。同时,把用户输入的字符串转换为浮点型然后赋值给了totalBill变量,使用的floatValue方法。第一步完成了。

接下来是确定小费费率,要检测用户选择的segments三个选项中哪一个,这样就确定了费率。Segmented Control有个属性是selectedSegmentIndex,这个属性能够告诉你用户现在选中的是哪个segment。在第二个注释后面按回车然后添加下列代码:

var index: Int = tipRateSegmentedControl.selectedSegmentIndex

这行代码创建了一个叫做index的新变量,同时把tipRateSegmentedControl选中的那个segment的值赋值给了index变量。index以零开头,index 0就是15%,index 1就是20%,index 2就是25%.

现在你已经知道了选中了哪个segment,你需要根据选中的segment得到对应的费率,这个地方适合用if条件句,在你写if条件句之前,先创建一个变量存储当前的费率:

var tipRate: Float = 0.15

这行代码创建一个浮点型变量tipRate。tipRate的默认值为0.15,tipRate会根据不同的segment转换不同的费率。在代码中写下下面的if语句:

var tipRate: Float = 0.15
if  index==0  {
     tipRate = 0.15
}

Page 94 | Chapter 3 : Diving into Swift

if条件句用if开头,接下来跟着条件。在这里,条件就是检查index的值是否是0,如果是0,那么返回true,如果不是0,返回false。如果条件为true,那么两个大括号直接的代码就会被执行,否则会跳过大括号里的代码,执行下一个条件。给if语句增加else if:

var tipRate: Float = 0.15

if index==0 {
    tipRate = 0.15
} else if index==1 {
    tipRate = 0.20
}

else if检查另外的条件,如果index是0,那么else if语句就不会执行,else if检查index的值是不是1,如果是1则为true,就会把0.20赋值给tipRate。增加if语句最后一部分:

var tipRate: Float = 0.15

if index==0 {
    tipRate = 0.15
} else if index==1 {
    tipRate = 0.20
} else {
    tipRate = 0.25
}

最后这部分,你添加了else语句,如果前两个if条件都不符合,那么就会触发else语句。在这里,index的值只有三种可能:0,1,2。else处理的是如果index为2的条件。

现在你已经有了总金额和小费费率,可以进行计算了。把你的鼠标光标放到第三行注释后面按回车,写下下列代码:

var tip: Float = totalBill * tipRate

这行代码创建了名为tip的浮点型变量,totalBill乘以tipRate后的值赋值给tip。这样,我们就完成了第三步。

把鼠标光标放到第四行注释后面按回车,然后输入下方的代码:

tipLabel.text = "$\\(tip)"

这行代码设置了tipLabel的text属性,我们用双引号来创建新的字符串,在字符串里面,先放一个美元的货币符合,然后()这部分是起着占位符的作用,可以存放任何变量,在这里,占位符中是tip变量。

这时点击Xcode的Play按钮(或者Command+R),iOS模拟器就会启动然后运行程序,App启动后,点击Text Field,输入一个数字,然后选择一个费率,点击Calculate按钮,Label中就会出现你需要付出的小费金额。

Exercise: Tip Calculator | Page 95

如果App没有按照你想要的结果运行,或者程序有了错误或警告,不要太担心,学习的最佳方式就是试错,熟能生巧,到我们的网站上下载示例代码,对比一下代码,多试几次,直到搞定这个程序为止。

Page 96 | Chapter 3 : Diving into Swift