21.4 表示层开发
从客观上讲,表示层开发的工作量是很大的,工作要做得很细致。
21.4.1 添加图片资源
首先需要把应用中要用的图片等资源添加到工程中。具体步骤如图21-13所示,右键选择Supporting Files组,选择菜单中的Add Files to “Calculator”…弹出选择文件对话框。如图21-14所示,选择我们提供的图片文件夹(images),并在Destination中选中Copy items if needed,这样可以将文件或文件夹复制到我们的工程目录中。在Add to folders中选择Create groups,可以在Xcode中创建images组。然后在Add to targets中选择Calculator。
图 21-13 添加图片资源文件
图 21-14 添加文件或文件夹对话框
由于图片资源文件很多,下面我们通过表21-3来解释一下它们的含义。
表21-3 图片资源文件
文件名 | 说明 |
---|---|
0.png~9.png | 0~9数字按钮默认状态显示的图片 |
0-down.png~9-down.png | 0~9数字按钮高亮状态显示的图片 |
c.png | 清除按钮默认状态显示的图片 |
c-down.png | 清除按钮高亮状态显示的图片 |
Decimal.png | 小数点按钮默认状态显示的图片 |
Decimal-down.png | 小数点按钮高亮状态显示的图片 |
Plus.png | 加按钮默认状态显示的图片 |
Plus-down.png | 加按钮高亮状态显示的图片 |
Minus.png | 减按钮默认状态显示的图片 |
Minus-down.png | 减按钮高亮状态显示的图片 |
Multiply.png | 乘按钮默认状态显示的图片 |
Multiply -down.png | 乘按钮高亮状态显示的图片 |
Divide.png | 除按钮默认状态显示的图片 |
Divide-down.png | 除按钮高亮状态显示的图片 |
Equals.png | 等号按钮默认状态显示的图片 |
Equals-down.png | 等号按钮高亮状态显示的图片 |
icon.png | 计算器应用图标 |
Cal.png | 主界面背景 |
21.4.2 改变设计界面大小
在开始界面设计之前,需要改变设计界面的大小。我们预计应用会在iPhone 5及之后的设备上发布,而且是竖屏,因此参考20.2节,通过图21-15所示的步骤改变设计界面大小。
图 21-15 改变设计界面大小
21.4.3 添加计算器背景
主界面中的计算器背景是一张图片,把图片放到界面中,需要将UIImageView控件添加到设计界面,具体操作可以参考20.2节。拖曳控件UIImageView到设计界面,然后选择属性检查器,选择Image View→Image为Cal.png。
为了保证UIImageView控件大小及高宽比与背景图片Cal.png保持一致,需要修改UIImage View尺寸等属性。选中右边的尺寸检查器,如图21-16所示的数值,设置坐标X和Y的属性,设置宽和高属性Width和Height。
图 21-16 修改UIImageView尺寸等属性
提示 原始背景图片大小是640×1136(像素),放到Retina显示屏幕中UIImageView控件大小就是320×568(像素),即高和宽减少了一半。这样设置后我们会发现设计界面下边还有空白(见图21-16),这是因为我们选择的设计界面高度是640点(1280像素),这没有关系,在iPhone 5设备上,下边多出的空白不会显示在屏幕上。
21.4.4 在设计界面中添加主标签
主界面中的主标签是用来显示输入数字和计算结果的控件,我们可以使用UILable控件。我们需要从控件库中拖曳一个Label到设计界面,并拖动它摆放到图21-17所示的位置和大小。如果你觉得拖曳不准确,可以设置它的尺寸属性,尺寸属性值X=0、Y=0、Width=320和Height=119。
图 21-17 添加Label
摆放好主标签控件的位置后,就需要设置它的文字相关属性。首先是颜色,选择主标签控件,打开属性检查器,设置Label→Color属性为白色,如图21-18所示。再设置Label→Alignment属性为右对齐,如图21-19所示。
图 21-18 设置主标签文字颜色
图 21-19 设置主标签文字对齐
然后设置文字字体,选择Label→Font属性,如图21-20所示,在弹出的对话框中设置Font为Custom(自定义),Family为Helvetica Neue,Style为Thin,Size为50。
图 21-20 设置主标签字体
当设置完成这些属性之后,我们需要选择Label标签,拖曳Label标签轮廓填充屏幕的宽度,效果如图21-21所示。
图 21-21 效果比较
21.4.5 在设计界面中添加按钮
从原型上看,主界面有17个按钮,我们先详细介绍其中一个按钮的设计过程,其他的以此类推。左上角的按钮是7,我们先来设计按钮7。从控件库中拖曳Button控件到设计界面,如图21-22所示。
图 21-22 添加Button控件
然后我们需要设置按钮的图片,由于按钮有4种状态,分别是Default(默认)状态、Highlighted(高亮)状态、Selected(选择)状态和Disabled(不可用)状态。每种状态都对应一套按钮风格,包括颜色、背景颜色、图片、背景图片以及字体等。状态切换如图21-23所示。
图 21-23 切换Button状态
在本例中,我们只设置默认状态下Image属性为7-down.png,高亮状态下Image属性为7-down.png。如图21-24所示,选择高亮状态,然后在下面的Image属性下拉列表中选择7-down.png。
图 21-24 选择特定状态下图片
接下来还需要设置按钮的大小,打开尺寸检查器,如图21-25所示,宽和高属性Width和Height设置为80。X和Y属性不需要在此设置。我们需要手动拖曳到左上角,具体位置参考原型设计图21-2。
图 21-25 设置按钮大小
依次按照按钮7的设计过程,设计其他16个按钮。全部设计完成后,界面如图21-26所示。
图 21-26 设计完成
为方便程序的计算,我们为主界面中的每一个按钮添加Tag
属性。具体过程是选中控件,打开右边的属性检测器,选择View→Tag属性,在这里输入该控件的Tag
值,Tag
属性默认为0。图21-27所示是设置“0”按钮的Tag
属性。按照此方法,参考表21-4,依次设置各个按钮的Tag
值。
图 21-27 设置Tag
属性
表21-4 按钮的Tag
属性值
按钮 |
Tag 属性值
|
---|---|
0~9数字按钮 | 100~109 |
小数点按钮 | 0 |
清除按钮 | 0 |
等于按钮 | 0 |
加运算符按钮 | 200 |
减运算符按钮 | 201 |
乘运算符按钮 | 202 |
除运算符按钮 | 203 |
21.4.6 控件的输出口和动作
为了将访问控件状态、事件和控件联系到一起,我们引入了输出口和动作的概念。
- 输出口
为了能够访问标签等控件,我们需要给标签定义并连接输出口。单击左上角第一组按钮中的“打开辅助编辑器”按钮,打开如图21-28所示的界面。
图 21-28 辅助编辑器
选中标签,同时按住control键,将标签主标签拖曳到图21-29所示的位置。
图 21-29 拖曳标签Label
释放鼠标,会弹出一个对话框。在Connection栏中选择Outlet,将输出口命名为mainLabel,如图21-30所示。
图 21-30 设置输出口
单击“Connect”按钮,右边的编辑界面将自动添加如下代码:
@IBOutlet var mainLabel: UILabel!
mainLabel
被声明为@IBOutlet
,这样就为主标签控件定义了输出口变量mainLabel
,就可以在程序中访问mainLabel
了,mainLabel
就是主标签控件的实例。
- 动作
为了响应按钮的事件,要把按钮事件与视图控制器中的方法管理起来。为此,需要将响应事件的方法声明为@IBAction
。此处列举一个动作的代码:
@IBAction func numberButtonPressed(sender: AnyObject) {
}
参数sender
是事件源,也就是发生动作事件的控件,AnyObject
是它的类型。
添加动作与输出口类似,打开辅助编辑器界面。选中按钮控件同时按住control键,将按钮控件拖曳到图21-31所示的位置。
图 21-31 拖曳按钮控件
释放鼠标,会弹出一个如图21-32所示的对话框,在Connection栏中选择Action,Name中输入“numberButtonPressed”,其他选项用默认值就可以。
图 21-32 定义动作
单击“Connect”按钮,右边的编辑界面将自动添加如下一行代码:
@IBAction func numberButtonPressed(sender: AnyObject) {
}
如果希望多个按钮共用一个方法,可以在拖曳第二个控件时候,直接把它拖曳到辅助编辑器的动作方法上。如图21-33所示,选中按钮控件,同时按住control键,将按钮控件拖曳到辅助编辑器的动作方法上,然后释放鼠标键,这样就可以为多个控件的动作定义一个方法了。类似输出口可以有多个控件对应一个输出口属性,设置方法与动作类似。
图 21-33 拖曳其他控件到动作方法
按照上面的方法依次为其他16个按钮添加动作,事件触发的方法请参考表21-5,其他的按钮设计这里不再赘述。
表21-5 按钮动作方法
按钮 | 触发的方法 |
---|---|
0~9数字按钮 |
numberButtonPressed
|
小数点按钮 |
decimalPressed
|
清除按钮 |
clearPressed
|
等于按钮 |
equalsPressed
|
运算符按钮 |
operandPressed
|
21.4.7 视图控制器
下面我们看看视图控制器ViewController.swift的代码,代码如下:
class ViewController: UIViewController {
@IBOutlet var mainLabel: UILabel!
var logic : CalcLogic! ①
override func viewDidLoad() { ②
super.viewDidLoad()
mainLabel.text = "0"
logic = CalcLogic()
}
override func didReceiveMemoryWarning() { ③
super.didReceiveMemoryWarning()
logic = nil
}
@IBAction func operandPressed(sender: AnyObject) { ④
var btn : UIButton = sender as UIButton ⑤
mainLabel.text = logic.calculateByTag(btn.tag, withMainLabelString: mainLabel.text) ⑥
}
@IBAction func equalsPressed(sender: AnyObject) {
var btn : UIButton = sender as UIButton
mainLabel.text = logic.calculateByTag(btn.tag, withMainLabelString: mainLabel.text)
}
@IBAction func clearPressed(sender: AnyObject) {
mainLabel.text = "0"
logic.clear()
}
@IBAction func decimalPressed(sender: AnyObject) {
if logic.doesStringContainDecimal(mainLabel.text) == false { ⑦
let string = mainLabel.text + "."
mainLabel.text = string
}
}
@IBAction func numberButtonPressed(sender: AnyObject) {
var btn : UIButton = sender as UIButton
mainLabel.text = logic.updateMainLabelStringByNumberTag(btn.tag,
withMainLabelString: mainLabel.text!) ⑧
}
}
上述代码第①行是声明CalcLogic
可变类型变量logic
。第②行代码重写UIViewController
父类的viewDidLoad()
方法。该方法在视图控制器加载时调用,我们在该方法中可以进行一些初始化。类似地,第③行的didReceiveMemoryWarning()
方法将在视图控制器卸载或内存报警时调用,我们在该方法中应该释放一些资源。
第④行代码operandPressed
方法是在用户点击运算符按钮时调用,第⑤行代码var btn: UIButton = sender as UIButton
是将参数sender
转换为UIButton
类型。转换为UIButton
类型后,才能通过访问UIButton
的属性和方法,例如tag
属性。第⑥行代码是调用业务逻辑层的calculateByTag
方法进行计算,返回结果用来更新mainLabel
内容。
第⑦行代码在用户点击小数点时调用,在该方法中判断mainLabel
标签中是否已经有小数点,如果没有则在mainLabel
后面拼接一个小数点。
第⑧行代码是在用户点击了数字按钮时调用的语句,通过调用业务逻辑层的updateMainLabelStringByNumberTag
方法,将更新之后的字符串重新设置到控件mainLabel
内容里。