第四章练习Race Car - 编写一个跑车App吧
在这个练习中,你将创建race car类,App会提供一辆赛车,点击Honk(按汽车喇叭),就会展示这赛车的详细信息。App的用户界面请见图4-1。
Exercise: Race Car | Page 105
界面上有六个Label和一个Button控件,App可以显示赛车的属性,用户可以点击Honk,点击Honk时,不会响起汽车喇叭声,而是会在开发者日志(developer log)中写下一段信息。
你已经知道了App有哪些功能,那么打开Xcode吧,点击顶部菜单栏的File -> New -> Project(见图4-2)。
Page 106 | Chapter 4 : Diving Deeper
从模板中选择Single View Application(见图4-3)。
点击Next,在Product Name一栏输入RaceCar(见图4-4)
Exercise: Race Car | Page 107
Organization Name和Organization Identifier已经自动填写好了,如果没有填写好,输入你的姓名中间不要有空格。最后,Language选择Swift,Devices选择iPhone,点击Next。
接下来从左侧选择你要存放的文件夹,点击Create,保存工程(见图4-5)。
Page 108 | Chapter 4 : Diving Deeper
出现了工程的详细信息界面(见图4-6)。Project Navigator在左边,Standard Editor在中间,Inspector在右边。
Exercise: Race Car | Page 109
点击Project Navigator中的Main.storyboard文件,出现一个空白界面(见图4-7)。
我们这次开发的App仅限于在iPhone上使用,点击Inspector的上方第一个按钮,看起来像是一张纸折了一个角。到中间部分,不勾选Use Auto Layout选项。这时会出现一个对话框,选择iPhone。然后不勾选Disable Size Classes。这时,Storyboard中的界面形状会改变(见图4-8)。我们将会在第七章详细介绍Auto Layout的知识。
Page 110 | Chapter 4 : Diving Deeper
确保Inspector在屏幕的右方。如果没有出现在屏幕右方,点击Inspector View Button(见图4-9),就是右上角右边有一条条纹的按钮,这样就可以显示Inspector了。
Inspector下方有个小的工具栏按钮,Object Library图标是从左往右第三个(圆圈中有个小方块)。
打开Object Library后,在搜索输入Label(见图4-10),将三个Label控件拖入到界面中,垂直对齐放在界面的右边(见图4-11)。
Exercise: Race Car | Page 111
三个Label对齐后,按住鼠标左键然后拖拽,覆盖三个Label,这样三个Label就被选中了(见图4-12),接着,到顶部菜单栏中选择Edit -> Copy或者按Command+C(见图4-13)。
Page 112 | Chapter 4 : Diving Deeper
接着到顶部菜单栏选择Edit -> Paste或者按Command+V(见图4-14)。
Exercise: Race Car | Page 113
这样又添加了三个Label控件,把这三个新的Label选中,然后拖到界面的右边,让Label对齐(见图4-15)。
Page 114 | Chapter 4 : Diving Deeper
有时候复制粘贴控件比起从Object Library中拖拽控件会更方便。最后,把Object Library搜索框中的label文字删掉,输入button(见图4-16)。
从Object Library中拖一个Button控件,放到两组Label中间(见图4-17)。
Exercise: Race Car | Page 115
双击界面左上角的Label,替换文字为Brand,双击左边中间的Label,文字更换为Color,最后双击左边最下方的Label,文字更换为Top Speed(见图4-18)。如有需要,重新调整Label的对齐。
Page 116 | Chapter 4 : Diving Deeper
右边Label中展示左边Label的具体值。见表格4-1。
表格4-1 | Race Car |
---|---|
品牌 | Ferrari |
颜色 | 红色 |
最高时速 | 200 mph |
双击Storyboard中的右侧的Label,然后问text修改为????(见图4-19)。然后将右侧的Label 宽度拖拽至60pts。
Exercise: Race Car | Page 117
最后,双击Button然后输入Honk,接着拖拽Button右上角的小方块,把宽度调整到60pts(见图4-20)。
Page 118 | Chapter 4 : Diving Deeper
现在,界面已经布局完成了,接下来需要把界面和controller连接起来。在这里,controller就是ViewController.swift文件。点击屏幕右上角的Assistant Editor按钮,打开Assistant Editor界面(见图4-21)。
为了能够有更多空间,我们把Inspector隐藏起来(点击屏幕右上角的Inspector View按钮)。
Assistant Editor会自动打开ViewController.swift文件,可以同上Assistant Editor顶部文件路径确认,就在Automatic这个词后面。
不是所有的控件都要连接到ViewController.swift文件中,如果这个控件是静态的或者无需变化,就没有必要连接。左侧的三个Label一直不变,那么就不需要连接。
选择右侧的Label,按住Control按钮,拖到下面这行代码的下方:
class ViewController: UIViewController {
当出现一条蓝色横线时,松开鼠标(见图4-22);弹出连接对话框窗口(见图4-23)。
Exercise: Race Car | Page 119
connection选择Outlet,Name输入brandLabel,点击Connect。
之后会自动生成一行代码:
@IBOutlet var brandLabel : UILabel!
第一个关键词@IBOutlet是来表示这是一个oulet连接类型,var表示这是一个变量,brandLabel就是这个变量的名字,冒号后面跟着变量的类型UILabel。brandLabel变量就代表了右侧最上面的Label。
Page 120 | Chapter 4 : Diving Deeper
然后选择界面上右侧中间的Label,同时按住Control键,拖到下面这行代码的下方:
class ViewController: UIViewController {
注意不要在brandLabel的代码上松开鼠标,如果你把鼠标错误的放到了其他的Label代码上方,和出现一个蓝色盒子。一定要在出现一条蓝色横线时,松开鼠标(见图4-24);弹出连接对话框窗口(见图4-25)。
connection选择Outlet,Name输入colorLabel,点击Connect。
Exercise: Race Car | Page 121
之后会自动生成一行代码。
然后选择界面上右侧底部的Label,同时按住Control键,拖到下面这行代码的下方:
class ViewController: UIViewController {
当出现一条蓝色横线时,松开鼠标(见图4-26);弹出连接对话框窗口(见图4-27)。
connection选择Outlet,Name输入topSpeedLabel,注意使用驼峰命名法,点击Connect。
会自动生成一行代码。
Page 122 | Chapter 4 : Diving Deeper
最后把Button连接到controller中。当用户点击Button时,Button会在controller中触发一个事件,这种连接模式叫做action。
选中界面中间的Button,同时按住Control键,拖到下面这行代码的下方:
class ViewController: UIViewController {
当出现一条蓝色横线时,松开鼠标(见图4-28);弹出连接对话框窗口(见图4-29)。
Exercise: Race Car | Page 123
因为这次连接的控件是Button,所以connection选择Action,点击Connection右侧的下拉菜单,选择Action,然后Name输入honkTapped,点击Connect。
会自动生成一行代码,Action连接创建的是方法,Outlet连接创建的是变量。每次用户点击Button时,honkTapped方法就会被调用。看一下Xcode生成的这段代码:
@IBAction func honkTapped(sender : AnyObject) {
}
第一个关键词@IBAction是来表示这是一个action连接类型,func表示这是一个方法,honkTapped就是这个方法的名字,括号内是方法的参数,括号里是参数的名字和类型,冒号后面就是这个参数的类型AnyObject。AnyObject起一个placeholder的作用,可用表示任何类型的对象。sender参数指向触发action的控件,sender参数根据控件的不同可以有很多不同的类型,像是Button,Slider,或者Segmented Control。
现在界面上所有需要连接的控件都已经连接到controller中了,是时候来创建你的race car了。然而,苹果并没有提供一个race car的类,没关系,你可以自己创建一个race car类。
选择File -> New -> File(见图4-30)
Page 124 | Chapter 4 : Diving Deeper
接着选择Cocoa Touch Class(见图4-31)。
Exercise: Race Car | Page 125
在Class一栏中输入RaceCar(见图4-32),Subclass设置为NSObject,Language选择Swift,点击Next。
Xcode接下来会让你选择存储地点,RaceCar工程已经自动选择了,如果没有,选择RaceCar文件夹,点击Create(见图4-33)。
Page 126 | Chapter 4 : Diving Deeper
这时在Project Navigator中有了一个新文件RaceCar.swift(见图4-34)。
Exercise: Race Car | Page 127
你的这个RaceCar类应该有三个属性和一个方法:brand,color,top speed以及honk方法,当RaceCar honk时,会在调试窗口打印出一行信息。开发者一般在调试窗口调试变量和事件。用户是无法看到developer log,这也是一个调试解决bug的好工具。
给你的RaceCar写下第一个属性:
class RaceCar: NSObject {
var brand: String = "Ferrari"
}
增加属性看起来像是在创建变量,不过属性是可以让其他对象获取的。var用了创建属性,var后面跟着属性名称,接着冒号后面跟着属性的类型,等号后面是属性的值,字符串用双引号括起来。
接着增加第二个属性:
class RaceCar: NSObject{
var brand: String = "Ferrari"
var color: String = "Red"
}
color属性的格式和语法与brand属性相同。属性名字是color,默认值是Red,类型是String,用户双引号将字符串的内容括起来。
最后,增加第三个属性:
class RaceCar: NSObject {
var brand: String = "Ferrari"
var color: String = "Red"
var topSpeed: Int = 200
}
topSpeed的属性多少有些不同了,类型是Int,因为最高时速是一个整型数字,所以默认值设置为200,属性是Int。
现在RaceCar类的属性已经都写完了,从RaceCar类中创建的车都会有brand,color和top speed这三个属性,默认值是"Ferrari","Red"和200。
RaceCar类还需要有一个honk行为,也就是honk方法,那么,我们把honk方法添加到RaceCar类中:
Page 128 | Chapter 4 : Diving Deeper
class RaceCar: NSObject {
var brand: String = "Ferrari"
var color: String = "Red"
var topSpeed: Int = 200
func honk() {
print("Honk! Honk!")
}
}
func关键词用来声明方法,honk是这个方法的名字,括号里是空的表示这个方法没有参数值。
在方法里面,用两个左右大括号包起来,只有一行代码,就是print这行代码,将"Honk! Honk!"打印到Debugger窗口中。
Debug Console或者Debugger(调试窗口),在写代码时候一般是隐藏的,当程序运行时,会出现(见图4-35)。打开Debugger的方法:屏幕右上角中间按钮,方块下方有一条横线的按钮,点击打开,再次点击隐藏。
现在RaceCar类已经写完了,那么,现在用RaceCar这个类来创建一辆跑车吧。快捷键Command+S保存刚刚的操作。
Exercise: Race Car | Page 129
点击打开Project Navigator里的ViewController.swift文件,点击右上角Standard Editor按钮来隐藏收起Assistant Editor。
把鼠标光标放到honkTapped方法中,然后添加下面的代码:
@IBAction func honkTapped(sender: AnyObject) {
//Create Car
//Display Car
//Honk Car
}
把鼠标光标放到//Create Car这行代码后面然后敲击回车,输入下列代码:
var myCar = RaceCar()
var用了创建变量,myCar是变量名,等号表示把等号右边的值复制给等号左边的变量。最后,用RaceCar()创建一个新的RaceCar。
RaceCar()调用RaceCar类的初始化方法,把默认值返回给这个新的RaceCar(也就是myCar)。这初始化方法是Xcode自动生成的。从一个类中创建对象,写下这个类的名字,后面跟上一对括号。在这里的这个例子中,没有参数,所以括号内是空的。
现在这个新的RaceCar赋给了myCar变量。把鼠标光标放到//Display Car后面然后敲击回车,写下下方代码:
brandLabel.text = myCar.brand
这行代码的作用是把myCar这个变量中的brand赋值给界面上brandLabel这个控件中text属性。在这里,brandLabel上显示的文字是"Ferrari",点这个符号可以获取Label的属性和方法,例如此处跟上了text这个属性。
myCar这个变量表示刚刚创建的新的RaceCar,后面的点符号可以获取RaceCar的属性和方法,例如此处获取了brand这个属性,这个属性返回一个string类型的值,和brandLabel的text属性类型对应一致。
在//Display后面敲击回车,输入下方代码:
colorLabel.text = myCar.color
topSpeedLabel.text = "\(myCar.topSpeed)"
你可能会注意到,colorLabel这行代码和上面的brandLabel代码非常相似。这行代码获取了RaceCar的color属性然后赋值给了colorLabel这个控件,默认值是"Red"。
Page 130 | Chapter 4 : Diving Deeper
topSpeed这行代码和前面两行稍微有些不同,topSpeedLabel这个控件应该显示的RaceCar的topSpeed这个属性,Label.text需要的是string类型的值,然后RaceCar的topSpeed这个属性的值是Int类型,类型不一致,需要转换,使用()即可转换。
鼠标光标放到//Honk后面,然后敲击回车,输入下方这行代码:
myCar.honk()
这行代码会触发RaceCar的honk方法(点符号可以获取对象的属性和方法),然后就会在Debugger中看到一行消息。括号里空的表示没有参数。
现在可以运行App看看效果了。点击左上角的Play按钮(或者快捷键Command+R),Xcode会启动模拟器(见图4-36)。
Exercise: Race Car | Page 131
App启动后,点击Honk这个按钮(见图4-37)。
RaceCar的属性都显示在对应的Label中了,点击Honk按钮后,会调用honk()方法,然后在Debugger中打印一段信息:“Honk! Honk!”
Page 132 | Chapter 4 : Diving Deeper
如果App没有按照你想要的结果运行,或者程序有了错误或警告,不要太担心,学习的最佳方式就是试错,熟能生巧,到我们的网站上下载示例代码,对比一下代码,多试几次,直到搞定这个程序为止。
Exercise: Race Car | Page 133