目 录
第1章 轻易进入iOS App设计殿堂 1
1.1 功能强大的Swift语言 2
1.2 开发前的准备工作 3
1.3 与 iOS App第一次接触 10
第2章 与应用程序互动:基本组件 20
2.1 Label组件 21
2.2 文字组件 31
2.3 Button组件 35
2.4 多按钮共享事件处理方法 43
第3章 让应用程序更生动:进阶组件 52
3.1 ImageView 组件 53
3.2 DatePicker组件 66
3.3 其他高级组件 79
第4章 让资料井然有序:表格组件 86
4.1 表格组件Table View 87
4.2 创建第一个Table View项目 92
4.3 单元格的选取和指示器的使用 95
4.4 编辑单元格 101
4.5 自定义单元格 107
4.6 创建静态方式的单元格 113
4.7 Collection View网格组件 115
第5章 给点提示吧:对话框及程序调试 120
5.1 对话框UIAlertView 121
5.2 对话框按钮触发的事件 126
5.3 程序调试 132
5.4 断点 134
第6章 海阔天空任遨游:网页组件 140
6.1 网页组件 Web View 141
6.2 多页面的项目 145
6.3 不同页面间的数据传递 149
6.4 综合范例 154
第7章 善用系统样板提高开发效率 166
7.1 Master-Detail样板 167
7.2 Page-Based样板 179
7.3 Tabbed样板 185
第8章 保存心血结晶:文件存取 193
8.1 NSUserDefaults类 194
8.2 读取项目中的文件 199
8.3 项目动态文件 205
第9章 结构化资料存取:资料库 219
9.1 SQLite数据库 220
9.2 Core Data数据库 240
第10章 动动手指就完成工作:手势 252
10.1 手势 253
第11章 来点影音调剂心情——多媒体 264
11.1 照相和图片的选取 265
11.2 声音的相关功能 271
11.3 视频的相关功能 294
第12章 快乐去旅行吧:位置及地图 301
12.1 CoreLocation 302
12.2 地图MapKit View 313
12.3 路径规划 327
附录 iOS实机测试 331
A.1 关于iOS的实体机测试 332
A.2 申请iOS开发者账号 332
A.3 注册付费的iOS Developer Program 338
A.4 创建并安装开发者凭证文件 343
A.5 注册开发的设备 348
A.6 实体机测试 349
第5章 给点提示吧:对话框及程序调试
UIAlertView组件可以显示对话框,制作按钮与用户互动,直到用户单击按钮后才关闭对话框并响应用户的按钮动作。
UIAlertViewStyle属性,可以设置对话框的样式,只要将属性设置为LoginAndPasswordInput,对话框中就会同时提供一个PlainTextInput和一个SecureTextInput,让用户输入账号和密码。
一般语法的错误中最常发生的是程序代码的输入错误,例如大小写不符、变量命名错误、找不到组件,或是类继承后却未按规定实现,这些错误通常会将鼠标指到错误的位置,再按照提示的错误信息进行修正。
5.1 对话框 UIAlertView
应用程序在执行过程中常会需要显示一个小信息告知用户一些必要信息,再根据用户响应内容进行适当的处理。
UIAlertView组件可以显示对话框,制作按钮与用户互动,直到用户按下按钮后才关闭对话框并响应用户的按钮动作。
UIAlertView的常用属性和方法,如表5-1所示。
表5-1 UIAlertView常用属性和方法
方法和属性 |
说明 |
title属性 |
设置对话框的标题 |
message属性 |
设置对话框的内容 |
delagate属性 |
设置对话框委托的对象 |
numberOfButtons属性 |
返回共有几个按钮 |
UIAlertViewStyle属性 |
设置对话框的样式。 Default:显示纯文字信息,默认值为Default PlainTextInput:提供输入文字后不会隐藏文字的文本框让用户输入数据 SecureTextInput:提供输入文字后会隐藏文字的文本框让用户输入数据 LoginAndPasswordInput:提供一个PlainTextInput和一个SecureTextInput,可以同时输入账号和密码 |
init()方法 |
默认构造函数 |
addButtonWithTitle()方法 |
按序创建按钮并设置按钮文字,返回创建按钮的索引值,第一个创建按钮的索引值为0 |
buttonTitleAtIndex()方法 |
返回指定索引的按钮文字 |
show()方法 |
显示对话框 |
alertView(alertView,clickButtonAtIndex)方法 |
按下按钮触发的事件,第一个参数alertView为触发的对象,第二个参数clickButtonAtIndex为按钮的索引值 |
textFieldAtIndex(index)方法 |
获取文本框,index=0获取账号,index=1获取密码 |
UIAlertView默认构造函数语法
init(title:String?, message:String?, delegate:AnyObject?,
cancelButtonTitle:String?)
UIAlertView组件的基本样式
UIAlertView组件的基本样式,如图5-1所示。
图5-1 UIAlertView组件的基本样式
对话框通常会显示标题、对话框的内容和按钮,按钮也可以同时创建多个。
创建UIAlertView主要有两种方式。
(1)继承UIAlertViewDelegate后,以构造函数创建UIAlertView对象,再用show()方法显示,语法如下:
var 变量名称 :UIAlertView = UIAlertView(title: 窗口标题 ,
message: 显示信息 , delegate: 委托对象 ,cancelButtonTitle: 第一个按钮文字 ,
[otherButtonTitles: 第二个按钮文字,其他按钮一,?]) 变量名称 .show()
cancelButtonTitle为创建的第一个按钮及按钮文字,默认最少要创建cancelButtonTitle按钮,否则会产生错误。
otherButtonTitles可以创建其他更多的按钮和按钮文字,如果按钮有多个,每个按钮以“,”号分隔。请注意:otherButtonTitles创建按钮的位置是从最上面按序往下排列。
按钮的排列
用构造函数创建对话框,会因为按钮数目不同而有不同的排列方式。当只有一个cancelButtonTitle按钮时,按钮排列在中间;如果对话中有两个按钮,cancelButtonTitle按钮的位置则是在最左方;但如果按钮太多,例如3个按钮或3个按钮以上,按钮会以垂直方式排列,此时cancelButtonTitle按钮的位置是在最下面而不是最上面。
例如:创建只包含一个cancelButtonTitle按钮的对话框,如图5-2所示。
图5-2 只含一个按扭的对话框
var alertView:UIAlertView = UIAlertView(title: " 窗口标题 ", message: " 这是样式默认为 Default 对话框。", delegate:self, cancelButtonTitle: " 第一个按钮 ")
alertView.show()
例如:创建包含cancelButtonTitle和一个otherButtonTitles按钮的对话框,如图5-3所示。
图5-3 包含cancelButtonTitle和一个otherButtonTitles按钮的对话框
var alertView:UIAlertView = UIAlertView(title: " 窗口标题 ", message: " 这是样式默认为 Default 对话框。", delegate:self, cancelButtonTitle: " 第一个按钮 ", otherButtonTitles:" 第二个按钮 ")
alertView.show()
例如:创建4个按钮的对话框,如图5-4所示。
图5-4 包含4个按钮的对话框
import UIKit
class ViewController: UIViewController,UIAlertViewDelegate { override func viewDidLoad() {
super.viewDidLoad()
// 用构造函数创建
var alertView:UIAlertView = UIAlertView(title: " 窗口标题 ",
message: " 这是样式默认为 Default 对话框。",
delegate:self, cancelButtonTitle: " 第一个按钮 ",
otherButtonTitles:" 第二个按钮 "," 第三个按钮 "," 其他按钮 ")
alertView.show()
}
}
继承UIAlertViewDelegate后,创建UIAlertView对象,设置其属性,并用addButtonWithTitle()方法加入按钮,再用show()方法显示。
用addButtonWithTitle()把按钮加入对话框,当只有一个或两个按钮时,按钮排列方式和用构造函数创建的对话框相同,但如果按钮太多,例如3个按钮或3个按钮以上,按钮会以垂直方式由下往下排列,此时第一个创建按钮的位置在最上面,如图5-5所示。
例如:前面的范例,用addButtonWithTitle()方法加入按钮的方式来创建。
图5-5 3个或3个以上按钮垂直排列
import UIKit
class ViewController: UIViewController,UIAlertViewDelegate { override func viewDidLoad() {
super.viewDidLoad()
// 创建对象并设置其属性和按钮
var alertView:UIAlertView = UIAlertView() alertView.title = " 窗口标题 "
alertView.message = " 这是样式默认为 Default 的对话框。"
alertView.delegate = self
alertView.addButtonWithTitle(" 第一个按钮 ")
alertView.addButtonWithTitle(" 第二个按钮 ")
alertView.addButtonWithTitle(" 第三个按钮 ")
alertView.addButtonWithTitle(" 其他按钮 ")
alertView.show()
}
}
用addButtonWithTitle()方法加入的按钮,会按加入的顺序从上往下排列。
范例:显示对话框
单击“显示对话框(一)”按钮,用init()构造函数创建对话框;按下“显示对话框(二)”钮,则创建UIAlertView对象,设置其属性,并用addButtonWithTitle()方法加入按钮的方式创建对话框,如图5-6所示(<AlertView01.xcodeproj>)。
图5-6 显示对话框
» 界面配置
创建Single View项目,项目名称为“<AlertView01>”。
打开Main.storyboard,分别加两个Button组件,如图5-7所示。
图5-7 添加Button组件
» 程序代码(ViewController.swift)
1 import UIKit
2
3 class ViewController: UIViewController,UIAlertViewDelegate {
4
5 @IBAction func alert1Click(sender: UIButton) {
6 // 用构造函数创建
7 var alertView:UIAlertView = UIAlertView(title: " 确认窗口 ", message: "
确定要结束应用程序吗 ?", delegate:nil, cancelButtonTitle: " 取消 ",otherButtonTitles:" 确定 ")
8 alertView.show()
9 }
10
11 @IBAction func alert2Click(sender: UIButton) {
12 // 创建对象并设置其属性和按钮
13 var alertView:UIAlertView = UIAlertView()
14 alertView.title = " 确认窗口 "
15 alertView.message = " 确定要结束应用程序吗 ?"
16 alertView.delegate = nil
17 alertView.addButtonWithTitle(" 取消 ")
18 alertView.addButtonWithTitle(" 确定 ")
19 alertView.show()
20 }
21~ 31 略
32 }
5.2 对话框按钮触发的事件
单击对话框按钮,会触发alertView(alertView,clickButtonAtIndex)事件,第一个参数alertView为触发的对象,第二个参数clickButtonAtIndex为按钮的索引值。只要依据按钮的索引值,即可以作对应的处理。请注意:要处理对话框的按钮事件,delegate必须设为self,若设为nil,将不会加以处理。
范例:对话框事件处理
单击“显示对话框”按钮,创建UIAlertView对象,并以addButtonWithTitle()方法加入按钮的方式创建对话框;在对话框中创建“取消”和“确定”两个按钮,单击“取消”和“确定”按钮,分别处理其触发事件,同时将按钮的文字返回labelResult卷标中显示,如图5-8所示。(<AlertView02.xcodeproj>)
图5-8 对话框事件处理
» 界面配置
创建Single View项目,项目名称为<AlertView02>。
打开Main.storyboard,加入一个View组件和一个Label组件,然后在View组件中再加入一个Button组件,如图5-9所示。
图5-9 界面配置
» 程序代码(ViewController.swift)
1 import UIKit
2
3 class ViewController: UIViewController,UIAlertViewDelegate {
4 @IBOutlet weak var buttonView: UIView!
5 @IBOutlet weak var labelResult: UILabel!
6 var buttonTitle:String = ""
7
8 override func viewDidLoad() {
9 super.viewDidLoad()
10 // 设置圆角按钮
11 buttonView.layer.cornerRadius = 10 // 圆角角度
12 }
13
14 // 单击按钮
15 @IBAction func buttonAlertClick(sender: UIButton) {
16 // 创建对象并设置其属性和按钮
17 var alertView:UIAlertView = UIAlertView()
18 alertView.title = " 确认窗口 "
19 alertView.message = " 确定要结束应用程序吗 ?"
20 alertView.delegate = self
21 alertView.addButtonWithTitle(" 取消 ")
22 alertView.addButtonWithTitle(" 确定 ")
23 alertView.show()
24 }
25
26 func alertView(alertView: UIAlertView!, clickedButtonAtIndex buttonIndex: Int){
27 // 获取按钮的文字
28 buttonTitle = alertView.buttonTitleAtIndex(buttonIndex)
29 labelResult.text=(" 您按下了 \(buttonTitle) 按钮 ")
30 switch (buttonIndex) {
31 case 0: // 单击“取消”按钮的处理
32 println(" 取消 ")
33 break
34 case 1: // 单击“确定”按钮的处理
35 println(" 确定 ")
36 break
37 default: // 其他的状况
38 println(" 错误 ")
39 }
40 }
41
42 }
UIAlertViewStyle 属性,可以设置对话框的样式,只要将属性设置为LoginAndPasswordInput,对话框中就会同时提供一个PlainTextInput和一个SecureTextInput,让用户输入账号和密码。
使用textFieldAtIndex(index)方法,可以获取UITextField类型的文本框,index=0会获取第一个文本框,index=1则获取第二个文本框,最后再用text属性即可获取文本框的内容。以LoginAndPasswordInput为例,index=0会获取账号,index=1则会获取密码。
范例:用对话框输入账号、密码
单击“登录系统”按钮,显示对话框,在对话框中输入正确账号“David”和密码“1234”后单击“登录”按钮,会在labelResult卷标中显示“欢迎光临”信息,否则显示“账号、密码错误”信息,如图5-10所示。(<AlertView03.xcodeproj>)
图5-10 用对话框输入账号、密码
» 界面配置
创建Single View项目,项目名称为“<AlertView03>”。
打开Main.storyboard,加入一个View组件和一个Label组件,然后在View组件中再加入一个Button组件,如图5-11所示。
图5-11 界面配置
» 程序代码(ViewController.swift)
1 import UIKit
2
3 class ViewController: UIViewController,UIAlertViewDelegate {
4 @IBOutlet weak var buttonView: UIView!
5 @IBOutlet weak var labelResult: UILabel!
6 let UserName:String = "David" // 账号
7 let Password:String = "1234" // 密码
8
9 override func viewDidLoad() {
10 super.viewDidLoad()
11 // 设置圆角按钮
12 buttonView.layer.cornerRadius = 10 // 圆角角度
13 }
14
15 // 单击按钮
16 @IBAction func buttonAlertClick(sender: UIButton) {
17 // 用构造函数创建对话框
18 var alertview=UIAlertView(title: " 登录 ",
19 message: " 欢迎光临 !",
20 delegate: self,
21 cancelButtonTitle: " 取消 ",
22 otherButtonTitles:" 登录 "
23 )
24 // 可输入账号和密码
25 alertview.alertViewStyle=UIAlertViewStyle.LoginAndPasswordInput
26 alertview.show()
27 }
28
29 func alertView(alertView: UIAlertView!, clickedButtonAtIndex buttonIndex: Int){
30 switch (buttonIndex) {
31 case 0: // 按下“取消”钮的处理
32 break
33 case 1: // 按下“登录”钮的处理
34 var textUserName:UITextField = alertView.textFieldAtIndex(0)!
35 var textPassword:UITextField = alertView.textFieldAtIndex(1)!
36 if (UserName == textUserName.text && Password == textPassword.text){
37 labelResult.text=(" 欢迎光临: \(textUserName.text)")
38 }else{
39 labelResult.text=(" 账号、密码错误 !")
40 }
41 break
42 default: // 其他的状况
43 println(" 错误 ")
44 }
45 }
46
47 }
5.3 程序调试
一个应用程序即使在设计期间编译都正确无误,但是到了运行期间,还是可能会发生一些无法预期的错误,例如:输入的数据类型不符、除数为0、打开的文件不存在、联网失败、数组的下标超出范围等等。
如何调试一直是程序设计师困扰的问题,而且没有良好的调试技巧,当面对大型或复杂的程序时,将会束手无策。
Swift应用程序错误的种类大致可分为语法错误、逻辑错误和执行时的错误,以下就各个状况进行说明。
语法的错误
一般语法的错误最常发生的是程序代码输入错误,例如大小写不符、变量命名错误、找不到组件,或是类继承后却未按规定实现,这些错误通常可以将鼠标指到错误的位置,再按提示的信息进行修正。例如:变量str误打为s产生Use of unresolved identifier 's'的错误,如图5-12所示。
图5-12 提示错误的信息
查询文件
Swift的语法太复杂,用户很难记住它的语法,通常查询文件是非常必要掌握的技巧,最简单的方式就是在所要查询的类上按住Command钮。此外,Swift也提供了另一种文件的查询方法,在主菜单上,单击Windows/Documentation and API Reference打开Documentation and API Reference窗口,然后输入要查询的信息,例如:查询AlertView类的使用方法,如图5-13所示。
图5-13 查询AlertView类
利用调试信息区显示信息
有经验的程序设计师,经常会利用程序调试信息区(Debug area),显示一些重要的信息,了解程序执行的状况,println()方法就是最常使用的方式。
类型错误的处理
Swift的类型定义非常严谨,当类型不对时,将会产生错误。要解决这个问题,可以将变量声明为Optional类型,当发生类型错误时,用println()输出信息来检验之。
例如:用textNum文本框输入n的值来求1 2 3 ... n之和,当文本框输入正确数值时可正常运算,然而当文本框未输入数据或输入的类型为文字时,将会产生错误。范例中,将变量n声明为Optional类型来处理,当发生类型错误时,就输出“类型错误!”信息,如图5-14所示。
图5-14 提示“类型错误”信息
var n:Int? = textNum.text.toInt()
if n == nil{
println("类型错误 !")
} else{
// 求 1 2 3 ? n 之和
}
5.4 断点
如果需要仔细追踪程序执行过程中变量或对象的内容,可以使用断点的设置,再利用Debug调试信息区来观察。
所谓断点,就是在程序的关键处加入停止点,当程序执行到该处时会暂停,开发者可以观察程序执行到此的变量、数组的值或内容,对于程序调试是相当重要的工具。
设置断点
在程序最左边,单击鼠标左键会出现蓝色的箭头,表示将该行程序设置为断点,应用程序执行到此设置的断点,即会中断并停留在此断点上。例如:在第9行设置断点,如图5-15所示。
图5-15 在第9行设置断点
取消断点
在已设置的断点上,再单击,该断点会变成灰色,表示取消该断点。例如:取消第9行断点,如图5-16所示。
图5-16 取消断点
删除断点
在断点处单击鼠标右键,在快捷菜单上单击Delete BreakPoint,即可将断点的设置删除。例如:删除第9行设置的断点,如图5-17所示。
图5-17 删除断点
程序调试信息区操作
程序调试信息区标题上提供调试的图标,方便程序调试,如图5-18所示。
图5-18 调试图标
①Toggle global beaakpoints state:断点状态切换,用以控制断点是否要起作用。②Continue program execution:继续执行程序。③Step Over:单步执行。④Step Into:进入方法或函数之中。⑤Step Out:离开目前的方法或函数。⑥显示对象和变量的信息。例如:变量n为Int?类型,其值等于5。
程序调试信息区左半部显示对象和变量信息,右半部则可以显示println()输出信息。对象和变量,也可以单击图标展开。例如:展开self可看到其中包含的对象,如图5-19所示。
图5-19 self中包含的对象
范例:以调试模式观察变量
用户输入数字n,单击“计算”按钮,程序会计算1 2 3 ? n之和,利用调试模式观察数字相加的过程。(<Debug.xcodeproj>)
输入5后单击“计算”按钮,得到结果15,输入空白或非数值,显示“类型错误”信息,如图5-20所示。
图5-20 计算结果与错误信息提示
» 界面配置
创建Single View项目,项目名称为<Debug>。
打开Main.storyboard,加入两个Label组件、一个textField组件和一个Button组件,如图5-21所示。
图5-21 界面配置
» 程序代码(ViewController.swift)
1 import UIKit
2
3 class ViewController: UIViewController {
4 @IBOutlet weak var textNum: UITextField!
5 @IBOutlet weak var labelResult: UILabel!
6
7 @IBAction func buttonClick(sender: UIButton) {
8 var n:Int? = textNum.text.toInt()
9 if n != nil{
10 var total:Int = calaulate(n!)
11 labelResult.text = " 总和 =\(total)"
12 }else{
13 println(" 类型错误 !")
14 }
15}
16
17 func calaulate(n:Int) -> Int {
18 // 求 1 2 3 ? n 之和
19 var sum:Int = 0
20 for var i:Int=0; i<=n; i {
21 sum = sum i
22 }
23 return sum
24 }
25
26 }
加入断点进行观察
请使用鼠标在<ViewController.swift>的第9、10、21行分别设置断点,然后单击工具栏上的图标执行该项目。
在textNum文本框中输入5,然后单击“计算”按钮,程序停在第9行的中断点上,并自动打开Debug Area窗口。在Debug Area可观察到变量n的值为5,也可以将鼠标移到要观察的变量上,将会显示该变量的值,如图5-22所示。
图5-22 显示变量的值
单击调试信息区的“单步执行”图标一次,程序停在第10行的断点上,准备执行calculate函数,这时total变量的值为0,如图5-23所示。
图5-23 单步执行
单击调试信息区的“继续执行”图标一次,程序停在第21行的断点上,表示执行已进入calculate函数,这时sum、i变量的值均为0,如图5-24所示。
图5-24 继续执行
再按“单步执行”图标,程序会在20~22行的for循环中单步执行,这时就可以观察sum、i变量。例如:按下键6次,变量sum=1、i=2,如图5-25所示。
图5-25 观察sum、i变量
也可以在执行过程中,再新增断点或删除已设置的断点。为了要快速离开for循环,请先用鼠标单击第21行的断点,该断点会变成灰色,表示已取消该断点,如图5-26所示。
图5-26 取消断点
然后单击“继续执行”图标一次,这时程序就会离开for循环,继续执行后面的程序代码,最后将总和total变量的值15显示在labelResult卷标上,如图5-27所示。
图5-27 在卷标上显示结果