** 1. Swift 语言程序设计(上)
*** 1. 关键字
1. [ ] 与声明有关的关键字
1. [ ] associatedtype, class, deinit, enum, extension, fileprivate, func,
import, init, inout, internal, let, open, operator, private,
protocol,public,static, struct, subscript,typealias 和 var。
2. [ ] 与语句有关的关键字
1. [ ] break, case, continue,defualt, defer, do, else,
fallthrough,for,guard,if,in,repeat,return,switch,where 和 while
3. [ ] 表达式和类型的关键字
1. [ ] as, Any,catch,false,is ,nil, rethrows, super,self,Self,throw,throws,
true 和 try。
4. [ ] 以#符号开头的关键字
1. [ ] #available, #colorLiteral, #column, #else, #elseif, #endif,
#file,#fileLiteral,#function,#if,#imageLiteral,#line,#selector和
#sourceLocation
5. [ ] 在特定 上下文中使用的关键字
1. [ ] associativity, convenience, dynamic, didSet, final, get, infix,
indirect, lazy, left, mutating, none, nonmuating, optional, override,
postfix, precedence, prefix, Protocol, required, right, set, Type,
unowned, weak 和 willSet
6. [ ] 下划线(_)关键字:表示模式匹配,可以替换任何字符
*** 2. 常量
1. [ ] let _hello = "Hello"
_hello = "Hello, World"//编译错误
2. [ ] var scoreForStudent = 0.0
var x = 10, y = 20
*** 3. 运算符
1. [ ] 算术运算符
2. [ ] 算术赋值运算符
3. [ ] 关系运算符
4. [ ] 逻辑运算符
5. [ ] 为运算符
let a: UInt8 = 0b1011 0010 (1)
let b: UInt8 = 0b0101 1110 (2)
print("a|b" = \(a|b)") //1111 1110 (3)
print("a&b" = \(a&b)") //0001 0010 (4)
print("a^b" = \(a^b)") //1110 1100 (5)
print("~a" = \(~a)") // 0100 1101 (6)
print("a >> 2 = \(a >> 2)") // 00101100 (7)
print("a << 2 = \(a << 2)") // 1100 1000 (8)
let: c:Int8 = -0b1100 (9)
print("c >> 2 = \(c>>2)") // -0000 0011 (10)
print("c << 2 = \(c<<2)") // -0011 0000 (11)
*** 4. Swift 数据类型
1. [ ] 值类型:整型,浮点型,布尔型,字符,字符串,元组,集合,枚举和结构体属于
值类型
2. [ ] 引用类型:类
3. [ ] 元组(tuple) 这个词很抽象,它是一种数据结构,在数学中应用广泛。在计算机科
学中,元组 是关系数据库中 的基本概念,元组表中的一条记录,每列就是一个字段。
定义一个 Studen 元组语法 表示就是
("1001", "张三”,30,90)// 第一种写法
(id: "1001", name:"张三", english_score:30, chinese_score:90)//第二种写法
let historyScore: UInt8 = 90
let englishScore: UInt16 = 130
let totalScore = historyScore + englishScore //错误
let totalScore = UInt16(historyScore) + englishScore//正确
let totalScore = historyScore + UInt8(englishScore) //正确
4. [ ] 可选类型的概念
1. [ ] Swift 为每一种数据类型提供了一种可选类型 (optional),即在某个数据类型后
面加上问号(?)或感叹号(!)
var n1: Int = 10
n1 = nil //发生编译错误
let str: String = nil //发生编译错误
// =====================
val n1: Int? = 10
n1 = nil
let str: String! = nil
var n1: Int? = 10
print(n1) //输出 Optional(10)
print(n1+100) //发生编译错误
//==========
var n1: Int? = 10
print(n1! + 100) //使用 问号(?) 声明的可选类型,在拆包时需要使用感叹号
(!),显示拆包
var n2: Int! = 100
print(n2 + 100) // 使用感叹号(!)声明的可选类型,在拆包时可以不使用感叹号
(!),隐式拆包
func divide(n1: Int, n2: Int) -> Double? {
if n2 == 0 {
return nil
}
return Double(n1)/Double(n2)
}
let result: Double? = divide(100, n2: 200)
//在 if 或 while 语句后,复制不需要拆包,可选绑定。
//防止出现 fatal error: unexpectedly found nil while unwrapping an
Optional value
if let result = divide(100, n2: 0) {
print(result)
print("Success.")
} else {
//print(result) //编译错误
print("failure")
}
5. [ ] 字符
1. [ ] Unicode 编码可以有单字节编码,双字节编码和四字节编码,它们的表现形式
是 \u{n}, 其中 n 为 1-个十六进制数
2. [ ] Unicode 编码可以在 http://vazor.com/unicode/ 网站查询字符与编码的对应关
系
3. [ ] 示例
let andSign1: Character = "&"
let andSign2: Character = "\u{26}"
let lambda1: Character = "λ"
let lambda2: Character = "\u{03bb}"
var smile1: Character = "笑脸表情"
var smile2: Character = "\u{0001f603"
4. [ ] 转义符
| 字符表示 | Unicode 编码 | 说 明 |
|----------+--------------+---------------|
| \t | \u{0009} | 水平制表符tab |
| \n | \u{000a} | 换行 |
| \r | \u{000d} | 回车 |
| \" | \u{0022} | 双引号 |
| \' | \u{0027} | 单引号 |
| \\ | \u{005c} | 反斜线 |
5. [ ] 字符串
1. [ ] 在 Switf 中字符串的类型是 String,String是一个结构体
let emptyString1 = ""
let emptyString2 = String()
2. [ ] String 字符串之间的拼接可以使用 + 和 += 运算符
String 字符串与字符拼接可以使用 String 的 append(_:Character)方法
var flower: Character = "flower"
flower.append("abc")
let total = "\(number) 加 10 等于 \(Double(number) + 10"
3. [ ] 字符串插入,删除和替换
1. [ ] 在索引位置插入字符
func insert(_newElement: Character, at i: String.index)
2. [ ] 在索引位置删除字符
func remove(at i: String.Index)->Character
3. [ ] 删除指定范围的字符串
func remove(at i:String.Index)->Character
4. [ ] 使用字符串或字符替换指定范围内的字符串
func replaceSubrange(_bounds: Range<String.Index>, with newElements:
String)
var str = "Objective-C And Swift"
print("原始字符串:\(str)")
//插入字符串
str.insert(".", at: str.endIndex)
print("插入.字符后:\(str)")
str.remove(at: str.index(before: str.endIndex))
print("删除.字符后:\(str)")
var startIndex = str.startIndex
var endIndex = str.index(startIndex, offsetBy: 9)
var range = startIndex...endIndex
//删除范围
str.removeSubrange(range)
print("删除范围后:\(str)")
startIndex = str.startInndex
endIndex = str.index(startIndex, offsetBy: 0)
range = startIndex...endIndex
//替换范围
str.replaceSubrange(range, with: "C++")
print("替换范围后:\(str)")
4. [ ] 字符串比较
1. [ ] 字符串类型与整型和浮点型一样,都可以进行相等以及大小的比较,比较
的依据是 Unicode 编码值大小。比较相等运算符 == 或!=
2. let emptystring1 = ""
let emptyString2 = String()
if emptystring1 == emptyString2 {
print("相等")
} else {
print("不相等")
}
var a = "a"
var b = "b"
if a > b {
print(">")
} else {
print("<")
|
6. [ ] 控制语句
1. [ ] 分支语句: if, switch 和 guard
循环语句: while, repeat-while 和 for
跳转语句: break, continue, fallthrough, return 和 throw
2. [ ] 1.分支语句
1. [ ] if 语句
1. if结构
if 条件表达式 {
语句组
}
2. if-else 结构
if 条件表达式 {
语句组1
} else {
语句组2
}
3. else-if 结构
if 条件表达式 {
语句组1
} else if 条件表达式2 {
语句组2
} else if 条件表达式n {
语句组n
} else {
语句组n+1
}
3. [ ] 2. switch 语句组
1. [ ] swift 中 switch 语句可以使用整数,浮点数,字符,字符串和元组等类型,
而且它的数值可以是离散的也可以是连续的范围
2. [ ] Swift 中的 switch 语句 case 分支不需要显式地添加 break 语句,分支执
行完成就会跳出 switch 语句
switch 条件表达式 {
case 值1:
语句组1
case 值2, 值3:
语句组2
case 值3:
语句组3
...
case 判断值n:
语句组n
default:
语句组n+1
}
3. [ ]
4. [ ] 3. guard 语句
guard 语句是 Swift2.x 新添加的关键字,与 if 语句非常类似,可以判断一个条件
为 true 情况下执行某语句,否则终止或跳过执行某语句。它的设计目的是替换复杂
if-else 语句的嵌套,提高程序的可读性
//定义一个 Blog(博客)结构体
struct Blog {
let name: String?
let URL: String?
let Author: String?
}
func ifStyleBlog(blog: Blog) {
if let blogName = blog.name {
print("这篇博客名:\(blogname)")
} else {
print("这篇博客没有名字")
}
func guardStyleBlog(blog: Blog) {
guard let blogName = blog.name else {
print("这篇博客没有名字")
\\ return
}
print("这篇博客名:\(blogName)")
}
}
func guardLongStyleBlog(blog: Blog) {
guard let blogName = blog.name else {
print("这篇博客没有名字")
return
}
print("这篇博客名:\(blogName)")
guard let blogAuthor = blog.Author else {
print("这篇博客没有作者")
return
}
print("这篇博客由\(blogAuhor)")
guard let blogURL = blog.URL else {
print("这篇博客没有网址")
return
}
print("这篇博客网址:\(blogURL)")
}
func ifLongStyleBlog(blog: Blog) {
if let blogName = blog.name {
print("这篇博客名:\(blogName)")
if let blogAuthor = blog.Author {
print("这篇博客由\(blog.Author)写的")
if let blogURL = blog.URL {
print("这篇博客的网址:\(blog.blogURL)")
} else {
print("这篇博客没有网址")
}
} else {
print("这篇博客没有作者")
}
} else {
print("这篇 博客没有名字")
}
}
5. [ ] 循环语句
1. [ ] while 循环条件 {
语句组
}
2. [ ] repeat {
语句组
} while 循环条件
var i: Int64 = 0
repeat {
i++
} while i*i < 100000
print("i=\(i)")
print("i*i=\(i * i)")
输出结果如下:
i = 317
i * i = 100489
3. [ ] for 语句
Swift 提供了一种专门遍历集合的 for 循环 -- for-in 循环。使用 for-in 循
环不必按照 for 的标准套路编写代码。你只需提供一个集合就可以遍历
计算 1~9 的平方表
print("n n*n")
print("----")
for i in 1 ..< 10 {
print("\(i) x \(i) = \(i * i)")
}
示例2
let numbers = [1,2,3,4,5,6,7,8,910]
print("---for----")
for var i =10; i < number.count;i++ {
print("Count is: \(i)")
}
4. [ ] 跳转语句
1. break 语句
break 语句用于 while ,repeat-while, for 和 for-in 循环结构,它的作
用是强行退出循环结构,不执行循环结构中的剩余的语句
2. break 语句有两种方式:可以带标签,也可以不带标签。语法格式如下:
break 不带标签
break label //带标签,label 是标签名
label 示例
label1: for x in 0..<5 {
label2: for y in (1..5).reversed() {
if y == x {
break label1
}
print("(x, y) = (\(x),\(y)")
}
}
print("Game Over")
3. continue 语句
continue 语句用来结束本次循环,跳过循环体中尚未执行的语句,接着进行
终止条件的判断,以决定是否继续循环
语法格式如下:
continue //不带标签
continue label //带标签, label 是标签名
4. fallthrough 语句
fallthrough 是贯通语句,只能使用在 switch 语句中。为了防止错误的发生,
Swift 中的 switch 语句 case 分支默认不能贯通,即执行完一个 case 分支
就跳出 switch。但是凡事都有例外,如果你的算法真的需要多个 case 分支
贯通,也可以使用 fallthrough 语句
var j = 1
var x = 4
switch x {
case 1:
j+=1
case 2:
j+=1
case 3:
j+=1
case 4:
j+=1
fallthrough
case 5:
j+1
fallthrough
default:
j+=1
}
6. [ ] 值绑定
有时候在一些控制语句中可以将表达式的值临时赋给一个常量或变量,这些常量或变
量能够在该控制语句中使用,这称为 "值绑定"
值绑定可以应用于 if,guard 和 switch 等控制语句中
1. [ ] if 中的值绑定
//定义一个 Blog(博客)结构体
struct Blog{
let name: String?
let URL: String?
let Author: String?
}
func ifStyleBlog(blog: Blog) {
if let blogName = blog.name,
let blogURL = blog.URL,
let blogAuthor = blog.Author {
print("这篇博客名:\(blogName)")
print("这篇博客由:\(blogAuthor)写的")
print("这篇博客网址:\(blogURL)")
} else {
print(”这篇博客信息不完整“)
}
}
let blog1 = Blog(name: nil, URL: "51work6.com", Author: "Tom")
let blog2 = Blog(name: "Tony Blog", URL: "51work6.com", Author: "Tony")
pritn("---blog1----")
ifStyleBlog(blog: blog1)
print("---blog2----")
ifStyleBlog(blog: blog2)
2. [ ] guard 中的值绑定
//定义一个Blog(博客)结构体
struct Blog {
let name: String?
let URL: String?
let Author: String?
}
func guardStyleBloe(blog: Blog) {
guard let blogName = blog.name,
let blogURL = blog.URL,
let blogAuthor = blog.Author else {
print("这篇博客信息不完整“)
return
}
print("这篇博客名:\(name)")
print("这篇博客由\(Author)")
print("这篇博客网址:\(blogURL)")
}
3. [ ] switch 中的值绑定
var student = (id: "1002", name:"李四”,age:32, ChineseScore:90,
EnglishScore:91)
var dest: String
switch student {
case (_, _, let AGE, 90...100, 90...100):
if (AGE > 30) {
desc = "老优"
} else {
desc = "小优"
}
case (_, _, _, 80..<90, 80..<90):
desc = "良"
case (_, _, _, 60..<80, 60..<80):
desc = "中"
case (_, _, _, 60..<80, 90..<100), ( _, _, _, 90...10, 60..<80):
desc = "偏科"
case ( _, _, _, 0..<80, 90...100), ( _, _, _, 90...100, 0..<80):
desc = "严重偏科"
default:
desc = "无"
}
print("说明:\(desc)")
7. [ ] 集合
1. [ ] 数组集合
数组( array ) 是一串有序的由相同类型元素构成的集合。数组中的集合元素是有序
的,可以重复出现。数组更关心元素是否有序,而不关心是否重复。
2. [ ] 数组声明和初始化
声明一个 Array 类型的时候可以使用下面语句之一
var studentList1: Array<String>
var studentList2: [String]
var studentList1: Array<String> = ["张三", "李四","王五","董六"]
var studentList2: [String] = ["张三", "李四", "王五","董六"]
let studentList3:[String] = ["张三", "李四", "王五","董六"]
var studentList4 = [String]()
3. [ ] 可变数组
var 声明的数组是可变数组,如果初始化之后不再修改数组,应该将数组声明为 let
的,即不变的数组。
对可变数组中的元素可以进行追加,插入,删除和替换等修改操作
追加元素 可以使用数组 append( _: ) 方法, + 和 += 操作符实现, + 和 += 操作符
能将两个数组合并一起,插入元素可以使用数组的 insert(_:at:)方法实现,删除元
素可以使用数组的 remove(at:) 方法实现
var studentList: [String] = ["张三", "李四","王五"]
print(studentList)
studentList.append("董六")
studentList+=["刘备“, ”关羽”]
print(studentList)
studentList.insert("张飞", at:studentList.count)
print(studentList)
let removeStudent = studentList.remove(at:0)
print(studentList)
studentList[0] = "诸葛亮"
print(studentList)
4. [ ] 数组遍历
1. [ ] 数组 最常用的操作是遍历,就是将数组中的每一个元素取出来,进行操作或
计算。整个遍历过程与循环分不开,我们可以使用 for 循环进行遍历
var studentList: [String] = ["张三", "李四", "王五"]
for item in studentList {
print(item)
}
for (index, value) in studentList.enumerated() {
print("Item \(index + 1):\(value)")
}
5. [ ] 字典集合
字典是由两部分集合构成的,一个是键(key) 集合,一个是值(value)集合。键集
合是不能有重复元素的,而值集合可以,键和值是成对出现的。
1. [ ] 字典的声明和初始化
声明一个 Dictionary 类型的时候可以使用下面语句之一:
var studentDictionary1: Dictionary<Int, String>
var studentDictionary2: [int: String]
var studentDictionary0: [Int: String]
var studentDictionary1: Dictionary<Int, String> = [102:"张三", 105:"李
四",109:"王五"]
var studentDictionary2 = [102:"张三", 105:"李
四",109:"王五"]
let studentDictionary3 = [102:"张三", 105:"李
四",109:"王五"]
var studentDictionary4 = Dictionary<Int, String>()
var studentDictionary5 = [Int: String]
2. [ ] 可变字典
var 声明的字典是可变字典,如果初始化之后不再修改字典 ,应该将字典声明为
let 的,即不变字典
1. 字典元素追加,只要给一个不存在的键赋一个有效值,就会追加一个 "键值"
对元素
2. 字典元素删除有两种方法:一种是给一个键赋值为 null, 这样就可以删除元
素;一种是通过字典的 removeValueForKey(_:)方法删除元素
1. 字典元素替换两种方法:一种是直接给一个存在的键赋值,这样 新值就会替
换旧值;另一种方法是通过 updateValue(_:forKey:)方法替换,方法的返回
值是要替换的值
var studentDictionary = [102: "张三", 105: "李四", 109: "王五"]
studentDictionary[110] = "董六"
print("班级人数:\(studentDictionary.count)")
let dimissStudent = studentDictionary.removeValue(forKey: 102)
print("开除的学生:\(dimisssStudent!)")
studentDictionary[105] = nil
studentDictionary[109] = "张三"
let replaceStudent = studentDictionary.updateValue("李四",
forKey:110)
print("被替换的学生是:\(replaceStudent!)")
1. 字典遍历
字典遍历集合也是字典的重要操作。与数组不同,字典有两个集合,因此遍
历过程可以只遍历值的集合,也可以只遍历键的集合,也可以同时遍历。这
些遍历过程都是通过 for-in 循环实现的。
var studentDictionary = [102: "张三", 105: "李四", 109: "王五"]
for studentID in studentDictionary.keys {
print("学号:\(studentID)")
}
for studentName in studentDictionary.values {
print("学生:\(studentName)")
}
for (studentID, studentName) in studentDictionary {
print("\(studentID): \(studentName)")
}
8. [ ] 函数
1. [ ] 定义函数
func 函数名(参数列表)-> 返回值类型 {
语句组
return 返回值
}
参数列表语法 :
(参数名:类型)
func rectangleArea(W width:Double, H height:Double) -> Double {
let area = width * height
return area
}
print("320x480 的长方形的面积:\(rectangleArea(W: 320, H:480))")
2. 函数调用
1. [ ] 使用参数标签
func rectangleArea(W width:Double, H height:Double) -> Double {
let area = width * height
return area
}
调用函数
print("320x480 的长方形的面积:\(rectangleArea(W: 320, H:480))")
1. [ ] 省略参数标签
func rectangleArea(W width:Double, H height:Double) -> Double {
let area = width * height
return area
}
调用函数
print("W x H 的长方形的面积:\(rectangleArea(320, 480))")
3. [ ] 函数类型
1. [ ] 每个函数都有一个类型,使用函数的类型与使用其他数据类型一样,可以声
明变量或常量,也可以作为其他函数的参数或者返回值使用
func sayHello() {
print("Hello,world")
}
函数类型是 ()->()
func rectangleArea(width: Double, height: Double) -> Double {
....
}
函数类型是(Double, Double) -> Double
4. [ ] 闭包
1. [ ] 支持函数类型,能够将函数作为参数或返回类型传递
2. [ ] 支持函数嵌套
3. [ ] 函数嵌套的示例
func calculate(opr: String)-> (Int, Int) -> Int {
var result: (Int, Int)-> Int
switch(opr) {
case "+":
result = {(a: Int, b: Int) -> Int in
return a+b
}
default:
result = {(a: Int, b: Int) -> Int in
return a-b
}
}
return result;
}
let f1: (Int, Int) -> Int = calculate("+")
print("10 + 5 = \(f1(10, 5))")
let f2: (Int, Int) -> Int = calculate("-")
print("10 + 5 = \(f2(10,5))")
// (Int, Int) -> Int
{(a:Int, b:Int) -> Int in //代替函数 add
return a+b
}
等价于
func add(a:Int, b:Int) ->Int {
return a+b
}
{(a:Int, b:Int) -> Int in //替代函数sub
return a-b
}
等价于
func sub(a:Int, b:Int) -> Int {
return a-b
}
5. [ ] Swift 闭包定义
闭包是自包含的匿名函数代码块,可以作为表达式,函数参数和函数返回值,
闭包表达式的运算结果是一种函数类型
Swift 中的闭包类似于 Objective-C 中的代码块,C++ 和 C# 中的 Lambda 表达式,
Java 中的匿名函数类
1. [ ] 使用闭包表达式
{(参数列表)-> 返回值类型 in
语句组
}
标准形式的闭包
{(a:Int , b:Int) -> Int in
return a+b
}
类型推断简化的闭包
{(a,b)in return a+b
}
{a, b in return a+b} 参数列表括号也可以省略
func calculate(opr: String)-> (Int, Int) -> Int{
var result: (Int, Int) -> Int
switch( opr ) {
case "+":
result ={a,b in return a + b;}
default:
result = {a, b in return a - b;}
}
return result
}
let f1:(Int, Int) -> Int = calculate("+")
prin("10 + 5 =\(f1(10,5))")
let f2:(Int, Int) -> Int = calculate("-")
print("10-5 =\(f2(10,5))")
2. [ ] 隐藏 return 关键字
如果在闭包内部语句组只有一条语句,如 return a+b 等,那么这种语句都是返
回语句。前面的关键字 return 可以省略,省略形式如下:
{a,b in a+b}
func calculate(opr: String) -> (Int, Int) -> Int {
var result: (Int, Int) -> Int
switch (opr) {
case "+":
result = {a, b in a + b}
default:
result = {a, b in a - b}
}
return result
}
3. [ ] 省略参数名
Swift 提供了参数名省略功能,我们可以用$0, $1, $2...来指定闭包中的参数:
$0 指代第一个参数,$1 指代第二个参数,$2 指代第三个参数,以此类推$n+1
指代第n个参数。参数名省略之后如下所示。
{$0 + $1}
func calculate(opr: String) -> (Int, Int) -> Int {
var result : (Int, Int) -> Int
switch (opr) {
case "+":
result = {$0 + $1}
default:
result = {$0 + $1}
}
return result
}
let f1:(Int, Int) -> Int = calculate("+")
print("10 + 5 = \(f1(10,5))")
let f2:(Int, Int) -> = calculate("-")
print("10 - 5 = \(f2(10, 5))")
4. [ ] 使用尾随闭包
闭包表达式可以作为函数的参数传递,如果闭包表达式很长,就会影响程序的可
读性。尾随闭包是一个书写在函数括号之后的闭包表达式,函数支持将其作为最
后一个参数调用
func calculate(opr: String, funN: (Int, Int) -> Int) {
switch(opr) {
case "+":
print("10+5 = \(funN(10, 5))")
default:
print("10 - 5 = \(funN(10, 5))")
}
}
calculate("+", funN:{(a:Int, b: Int)->Int in return a + b})
calculate("+") {
(a: Int, b: Int) -> Int in return a + b
}
calculate("-") {
(a: Int, b: Int) -> Int in
return a - b
}
calculate("-") {
$0 - $1
}
5. [ ] 捕获上下文中的变量和常量
嵌套函数或闭包可以访问它所在上下文的变量和常量,这个过程称为捕获值
(capturing value)。即便是定义这些常量和变量的原始作用域已经不存在,嵌
套函数或闭包仍然可以在函数体内或闭包体内引用和修改这些值
func makeArray() -> (String) -> [String] {
var ary:[String] = [String]()
func addElement(element:String) -> [String] {
ary.append(element)
return ary
}
return addElement
}
let f1 = makeArray()
print("---f1---")
print(f1("张三”))
print(f1("李四"))
print(f1("王五"))
print("---f2---")
let f2 = makeArray()
print(f2("刘备"))
print(f2("关羽"))
print(f2("张飞"))
** 2. Swift 语言程序设计(下)
*** 1. Swift 中的面向对象类型
1. [ ] 在 Swift 语言中类,结构体(Struct) 和枚举(enum) 都是面向对象的数据类型,
具有面向对象的特征。而在其他语言中,结构体和枚举是完全没有面向对象特性的,
Swift 语言赋予了它们面向对象特征
1. [ ] 枚举: 在 C 和 Objective-C 中,枚举用来管理一组相关常量集合,通过使用
枚举可以提高程序的可读性,使代码更清晰,更易维护。
而在 Swift 中,枚举的作用已经不仅仅是定义一组常量,提高程序的可读性了,它
还具有了面向对象特性
我们先来看 Swift 声明 。Swift 中也是使用 enum 关键词声明枚举类型,具体定义
放在一对大括号内,枚举的语法格式如下:
enum 枚举名
{
枚举的定义
}
2. [ ] 声明枚举
而在 Swift 中,枚举的成员值默认情况下不是整数类型,以下代码是声明枚举的示
例:
enum WeekDays {
case Monday
case Tuesday
case Wednesday
case Thursday
case Friday
}
也可以将多个成员值放在同一行,用逗号隔开,如下所示:
enum WeekDays {
case Monday, Tuesday, Wednesday, Thursday, Friday
}
var day = WeekDays.Friday
day = WeekDays.Wednesday
day =.Monday
func writeGreeting(day : WeekDays) {
switch day {
case .Monday:
print("星期一好!")
case .Tuesday:
print("星期二好!")
case .Wednesday:
print("星期三好!")
case .Thursday:
print("星期四好!")
case .Friday:
print("星期五好!")
}
}
writeGreeting(day)
writeGreeting(weekDays.Friday)
3. [ ] 类和结构体定义
1. [ ] class 类名 {
定义类的成员
}
struct 结构体名 {
定义结构体的成员
}
类图
| <<Class>> |
| Employee |
|------------------------|0..* 0..1
| var no:Int = 0 |---------------
| var name:String = "" |
| var job: String? |
| var salary: Double = 0 |
| var dept: Department? |
| |
| <<Student>> |
| Department |
|---------------------|
| var no: Int = 0 |
| var name: String="" |
| |
| |
示例
class Employee {
var no: Int = 0
var name: String = ""
var job: String?
var salary: Double = 0
var dept: Department?
}
struct Department {
var no: Int = 0
var name: String = ""
}
let emp = Employee()
var dept = Department()
*** 2. 可选链
1. [ ] 可选链的概念
| <<Class>> | | <<Class>> | | <<Class>> |
| Employee | | Department | | Company |
|------------------------+-----+-----------------------+-----+----------------------|
| var no:Int = 0 | | var no: Int = 0 | | var no: Int = 0 |
| var name: String = "" | | var name: String = "" | | var name: String ="" |
| var job: String? | | var comp:Company? | --> | |
| var salary: Double = 0 | | | | |
| var dept: Department? | --> | | | |
| | | | | |
2. [ ] 无可选链
class Employee {
var no: Int = 0
var name: String = "Toney"
var job: String?
var salary: Double = 0
var dept : Department = Department()
}
class Department {
var no : Int = 10
var name : String = "SALES"
var comp : Company = Company()
}
class Company {
var no : Int = 1000
var name : String = "Eorient"
}
3. [ ] 可选链
class Employee {
var no : Int = 0
var name : String = "Toney"
var job : String?
var salary : Double = 0
var dept : Department? //= Department()
}
clas Department {
var no : Int = 18
var name : String = "SALES"
var comp : Company? //=Company()
}
class Company {
var no : Int = 1000
var name : String = "Eorient"
}
var emp = Employee()
print(emp.dept!.comp!.name) //显示拆包
print(emp.dept?.comp?.name) //可选链
4. [ ] 使用问号(?)和 感叹号(!)
1. [ ] 可选类型中的问号(?)
声明这个类型是可选类型 ,访问这种类型的变量或常量时要使用感叹号(!),下
列代码是显示拆包:
let result1:Double? = divide(100, 200)//声明可选类型
print(result1!)//显示拆包取值
声明这个类型也是可选类型,但是访问这种类型的变量或常量时可以不使用感叹号
(!),下列代码是隐式拆包:
let result3: Double! = divide(100, 200) //声明可选类型
print(result3) //隐式拆包取值
2. [ ] 可选类型中的问号(?)
在可选链中使用感叹号(!)访问时,一旦“链条”某些环节没有值,程序就会发生异
常,于是我们把感叹号(!)改成问号(?),代码如下所示:
emp.dept?.comp?.name
*** 3. 访问限定
1. [ ] 访问范围
模块。模块是指一个应用程序包或一个框架
源文件。源文件指的是 Swift 中的 .swift 文件
2. [ ] 访问级别
Swift 提供了5种不同访问级别,对于的访问修饰符: open,public, internal,
fileprivate和private。这些访问修饰符可以修饰类,结构体,枚举等面向对象的类型,
还可以修饰:变量,常量,下标,元组,函数,属性等内容。
open: 访问限制最小的,任何 open 实体,无论在自己模板内部,还是其他模板
(import语句引入其他模板后)都可以被访问。
public: 类似于 open,在同一个模块中 open 和 public 完全一样。在不同模块时
public 所声明的类不能被继承,public 所声明的属性和方法不能被重写(override)
internal: 缺省访问限定。internal 实体只能在自己模块被访问
fileprivate: 只能在当前源文件中被访问
private: 是真正意义上的 ”私有“, 只能在类型内部被访问
3. [ ] 使用访问级别最佳实践
1. [ ] 统一性原则
原则1:。如果一个类型(类,结构体,枚举)定义为 internal 或 private ,那么
类型声明的变量或常量不能使用 public 访问级别
原则2。函数的访问级别不能高于它的参数和返回类型(类,结构体,枚举)的访问
级别
示例
private class Employee {
var no: Int = 0
var name: String = ""
var job: String?
var salary: Double = 0
var dept: Department?
}
internal struct Department {
var no: Int = 0
var name: String = ""
}
public let emp = Employee() //编译错误
public var dept = Department() //编译错误
class Employee {
var no: Int = 0
var name: String = ""
var job: String?
var salary: Double = 0
var dept: Department?
}
struct Department {
var no: Int = 0
var name: String = ""
}
public func getEmpDept(emp: Employee) -> Department? {//错误
return emp.dept
}
2. [ ] 设计原则
如果我们编写的是应用程序,应用程序包中的所有 Swift 文件和其中定义的实体都
是供本应用使用的,而不是提供给其他模块使用,那么我们就不用设置访问级别了,
即使用默认的访问级别
如果我们开发的是框架,框架编译的文件不能独立运行,因此它天生就是给别人使用
的,这种情况下要详细设计其中的 Swift 文件和实体的访问级别,让别人使用的可
以设定为 public ,不想让别人看到的可以设定为 internal 或 private
3. [ ] 元组类型的访问级别
元组类型的访问级别遵循元组中字段最低级的访问级别,例如下面的代码
private class Employee {
var no: Int = 0
var name: String = ""
var job: String?
var salary: Double = 0
var dept: Department?
}
struct Department {
var no: Int = 0
var name: String =""
}
private let emp = Employee()
var dept = Department()
private var student1 = (dept, emp)
4. [ ] 枚举类型的访问级别
枚举中成员的访问级别继承自该枚举,因此我们不能为枚举中的成员指定访问级别。
例如下面的代码
public enum WeekDays {
case Monday
case Tuesday
case Wednesday
case Thursday
case Friday
}
*** 4. 属性
1. [ ] 属性
存储属性可以存储数据,分为常量属性(用关键字 let 定义)和变量属性(用关键
字 var 定义)。存储属性适用于类和结构体两种 Swift 面向对象类型
| <<Class>> | | <<Struct>> |
| Employee | | Department |
|------------------------+------------+-----------------------|
| var no: Int = 0 | | var no: Int = 0 |
| var name: String = "" | | var name: String = "" |
| var job: String? | 0..* 0..1 | |
| var salary: Double = 0 | ---------- | |
| var dept: Department? | | |
| | | |
实例
class Employee {
let no: Int = 0
var name: String = ""
var job: String?
var salary: Double = 0
var dept: Department?
}
struct Department {
let no: Int = 0
var name: String = ""
}
let emp = Employee()
emp.no = 100 //编译错误
let emp1 = Employee()
emp1.name = "Tony"
2. [ ] 计算属性
计算属性本身不存储数据,而是从其他存储属性中计算得到数据。与存储属性不同,
类,结构体和枚举都可以定义计算属性
面向对象类型 类型名 {
存储属性
...
var 计算属性名: 属性类型数据 {
get {
return 计算后属性值
}
set (新属性值){
....
}
}
}
3. [ ] 计算属性概念
class Employee {
var no: Int = 0
var firstName: String = "Tony"
var lastName: String = "Guan"
var job: String?
var salary: Double = 0
lazy var dept: Department = Department()
var fullName: String {
get {
return firstName + "." + lastName
}
set(newFullName){
let name = newFullName.componts(separatedBy:".")
firstName = name[0]
lastName = name[1]
}
}
}
struct Department {
let no: Int = 0
var name: String = ""
}
var emp = Employee()
print(emp.fullName)
emp.fullName = "Tom.Guan"
print(emp.fullName)
4. [ ] 只读计算属性
class Employee {
var no: Int = 0
var firstName: String = "Tony"
var lastName: String = "Guan"
var job: String?
var salary: Double = 0
lazy var dept: Department = Department()
var fullName: String {
return fristName + "." + lastName
}
}
struct Department {
let no: Int = 0
var name: String = ""
}
var emp = Employee()
print(emp.fullName)
5. [ ] 静态属性
有一个 Account (银行账户)类,假设它有3个属性:amount(账户金额),
interestRate(利率)和 owner(账户)。在这3个属性中,amount 和 owner 会因人
而异,不同的账号这些内容是不同的,而所有账户的 interestRate 都是相同的
amount 和 owner 属性与账户个体有关,称为实例属性。interestRate 属性与个体
无关,或者说是所有账户个体共享,这种属性称为静态属性或类型属性
6. [ ] 结构体静态属性语法格式
struct 结构体名 {
static var(或 let) 存储属性 = "xxx"
...
static var 计算属性名:属性数据类型 {
get {
return 计算后属性值
}
set(新属性值) {
...
}
}
}
示例
struct Account {
var amount: Double = 0.0 //账户余额
var owner: String = "" //账户名
static var interestRate: Double = 0.0668 //利率
static var staticProp: Double {
return interestRate * 1000000
}
var interestRate: Double {
return Account.interestRate = account
}
}
访问静态属性
print(Account.staticProp)
var myAccount = Account()
//访问实例属性
myAccount.amount = 1000000
//访问实例属性
print(myAccount.instanceProp)
7. 枚举静态属性语法格式
enum 枚举名 {
static var(或let) 存储属性 = "xxx"
...
static var 计算属性名: 属性数据类型 {
get {
return 计算后属性值
}
set(新属性值) {
...
}
}
}
示例
enum Account {
case 中国银行
case 中国工商银行
case 中国建设银行
case 中国农业银行
static var interestRate: Double = 0.668 //利率
static var staticProp: Double {
return interestRate * 1000000
}
var instanceProp: Double {
swift (self) {
case .中国银行:
Account.interestRate = 0.667
case .中国工商银行:
Account.interestRate = 0.669
case .中国建设银行:
Account.interestRate = 0.666
case .中国农业银行:
Account.interestRate = 0.668
}
return Account.interestRate * 1000000
}
}
//访问属性
print(Account.staticProp)
var myAccount = Account.中国工商银行
//访问实例属性
print(myAccount.instanceProp)
8. [ ] 类静态属性语法格式
class 类名 {
static var(或let) 存储属性 = "xxx"
...
class(或static) var 计算属性名:属性数据类型 {
get {
return 计算后属性值
}
set (新属性值){
...
}
}
}
示例
class Account {
//账号金额
var amount: Double = 0.0
//账号名
var owner: String = ""
//利率
static var interestRate: Double = 0.0668
//class 换成 static 不能重写该属性
class var staticProp: Double {
return Account.interestRate * self.amount
}
}
class AccountB: Account {
override class var staticProp: Double {
return interestRate = 1000000
}
}
//访问静态属性
print(Account.staticProp)
var myAccount = Account()
//访问实例属性
myAccount.amount = 1000000
//访问静态属性
print(myAccount.instanceProp)
9. [ ] 类静态属性
类中不仅可以定义实例存储属性,还可以定义静态存储属性,声明静态存储属性的
关键字是 static
类中也可以定义静态计算属性,声明使用的关键字是 class 或 static ,类静态计
算属性如果使用 static 定义,则该属性不能在子类中被重写(override);如果使
用 class 定义,则该属性可以被子类重写。
10. [ ] 归纳面向对象类型属性
| 面向对象类型 | 实例存储属性 | 静态存储属性 | 实例计算属性 | 静态计算属性 |
|--------------+--------------+--------------+--------------+--------------|
| 类 | 支持 | 支持 | 支持 | 支持 |
| 结构体 | 支持 | 支持 | 支持 | 支持 |
| 枚举 | 不支持 | 支持 | 支持 | 支持 |
*** 5. 方法
1. [ ] 实例方法
实例方法与实例属性类似,都隶属于枚举,结构体或类的个体(即实例),我们通过实
例化这些类型创建实例,使用 实例调用的方法
class Account {
var amount: Double = 10000.00
var owner: String = "Tony"
//计算利息
func interestRate(rate: Double) -> Double {
return rate * amount
}
}
var myAccount = Account()
//调用实例方法
print(myAccount.interestRate(0.088))
2. [ ] 静态方法
静态方法的定义与静态属性类似,枚举和结构体的静态方法使用的关键字是 static ,
类静态方法使用的关键字是 class 或 static ,如果使用 static 定义,则该方法不能
在子类中被重写(override);如果使用 class 定义,则该方法可以被子类重写
3. [ ] 结构体静态方法
struct Account {
var owner: String = "Toney" //账号名
static var interestRate: Double = 0.668 //利率
static func interestBy(amount: Double) -> Double{
print(self)//打印数据类型
return interestRate * amount
}
func messageWith(amount: Double) -> String {
let interest = Acount.interestBy(account: account)
return "\(self.owner) 的利息是\(interest)"
}
}
//调用静态方法
print(Account.interestBy(amount: 10000.00))
var myAccount = Account()
//调用实例方法
print(myAccount.messageWith(account: 10000.00)
4. [ ] 枚举静态方法
enum Account {
case 中国银行
case 中国工商银行
case 中国建设银行
case 中国农业银行
static var interestRate: Double = 0.668 //利率
static func interestBy(amount: Double) -> Double {
}
}
//调用静态方法
print(Account.interestBy(amount: 10000.00))
5. [ ] 类静态方法
class Account {
//账号名
var owner: String = "Tony"
//class 换成 static 不能重写该方法
class func interestBy(amount: Double) -> {
return 0.08886 *amount
}
}
class AccountB: Account {
override static func interestBy(amount: Double) -> Double {
return 0.0889 * amount
}
}
//调用静态方法
print(Account.interestBy(amount: 10000.00))
*** 6. 构造函数
结构体和类的实例在构造过程中会调用一种特殊的 init 方法,称为构造函数。构造函
数没有返回值,可以重载。在多个构造函数重载的情况下,运行环境可以根据它的外部
参数名或参数列表调用合适的构造函数
类似的方法再 Objective-C 和 C++ 也称为构造函数, Java 中称为构造方法。不同的
是,Objective-C 中的构造函数有返回值,而 C++ 和 Java 中的构造函数必须与类名
相同,没有返回值
1. [ ] 类默认构造函数
class Rectangle {
var width: Double = 0.0
var height: Double = 0.0
}
var rect = Rectangle()
rect.width = 320.0
rect.height = 480.0
print("长方形:\(rect.width)%\(rect.heigth)")
2. [ ] 结构体默认构造方法
struct Rectangle {
var width: Double = 0.0
var height: Double = 0.0
// init() {}
// init(width: Double, height: Double) {
// self.width = width
// self.height = height
// }
}
var rect = Rectangle()
rect.width = 320.0
rect.height = 480.0
print("长方形:\(rect.width) x \(rect.heigth)")
var rectb = Rectangle(width: 320, height: 480)
3. [ ] 构造函数与储存属性初始化1
class Rectangle {
var width: Double
var height: Double
init() {
width = 0.0
height = 0.0
}
}
var rect = Rectangle()
rect.width = 320.0
rect.height = 480.0
print("长方形:\(rect.width) x \(rect.height)")
4. [ ] 构造函数与储存属性初始化2
class Employee {
let no: Int
var name: String?
var job: String?
var salary: Double
var dept: Department?
init() {
no = 0
salary = 0
dept = null
}
}
struct Department {
let no: Int
var name: String
init() {
no = 10
name = "SALES"
}
}
let dept = Department()
var emp = Employee()
*** 7. 析构函数 (62)
1. [ ] 与构造过程相反,实例最后释放的时候需要清除一些资源,这个过程就是析构过程。
析构过程中也会调用一种特殊的方法deinit, 称为 析构函数。析构函数 deinit 没有返
回值,也没有参数,也不需要参数的小括号,所以不能重载
class Rectangle {
var width: Double
var height: Double
init(width: Double, height: Double) {
self.width = width
self.height = height
}
init(W width: Double, H height: Double) {
self.width = width
self.height = height
}
deinit() {
print("调用析构器...")
self.width = 0.0
self.height = 0.0
}
}
var rectcl: Rectangle? = Rectangle(width: 320, height: 480)
print("长方形:\(rectcl!.width) x \(rectcl!.height)")
rectcl = nil
var rectc2: Rectangle? = Rectangle(W: 320, H: 480)
print("长方形:\(rect2!.width) x \(rectc2.height)")
rectc2 = nil
*** 8. 类继承
1. [ ] 继承概念
//类 Person
class Person {
var name: String
var age: Int
func descripteion() -> String {
return "\(name) 年龄是:\(age)"
}
init() {
name = ""
age = 1
}
}
class Student: Person {
var school: String
override init() {
school = ""
super.init()
age = 8
}
}
//类 Student
class Student {
var name: String
var age: Int
var school: String
func descripteion -> String {
return "\(name) 年龄是:\(age)"
}
init() {
school = ""
name = ""
age = 8
}
}
2. [ ] 构造函数继承
1.[ ] 类构造函数代理分为横向代理和向上代理,横向代理只能在发生在同一个类内部,
这种构造函数称为便利构造函数。向上代理发生在继承的情况下,在子类构造过程中,
要先调用父类构造函数初始化父类的存储属性,这种构造函数称为指定构造函数
class Person {
var name: String
var age: Int
func descripteion() -> String {
return "\(name) 年龄是:\(age)"
}
convenience init() {//便利构造函数,横向代理
self.init(name: "Tony")
self.age = 18
}
convenience init(name: String) {//便利构造函数,横向代理
self.init(name: name, age: 18)
}
init(name: String, age: Int) {
self.name = name
self.age = nage;
}
}
class Student: Person {
var school: String
init(name: String, age: Int, school: String) {//指定构造函数,向上代理
self.school =school
super.init(name: name, age: age)
}
convenience override init(name: String, age: Int) {
self.init(name: name, age: age, school: "清华大学")
}
}
3. [ ] 构造函数调用规则
1. [ ] 指定构造函数必须调用其直接父类的指定构造函数。 Student 中的4号指定构造
函数调用 Person 中的 3 号指定构造函数
2. [ ] 便利构造函数必须调用同一类中定义的其他构造函数。Student 中 5 号便利构
造函数调用同一类中的 4 号构造函数,Person 中的 1 号便利构造函数调用同一类
中的 2 号构造函数
3. [ ] 便利构造函数必须最终以调用一个指定构造函数结束。 Student 中的 5 号便利
构造函数调用同一类中的 4 号指定构造函数。 Person 中的 2 号便利构造函数调用
同一类中的 3 号指定构造函数
4. [ ] 重写
1. [ ] 一个类继承另一个类的属性和方法等特征后,子类可以重写(override) 这些特
征。下面就逐一介绍这些特征的重写
2. 重写实例属性
在子类中重写从父类继承来的属性,属性的重写一方面可以重写 getter 和 setter
访问函数,另一方面可以重写属性观察者
3. 重写 getter 和 setter 访问函数
class Person {
var name: String
var age: Int
...
}
class Student: Person {
var school: String
cverride var age: Int {
get {
return super.age
}
set {
super.age = newValue < 8 ? 8: newValue
}
}
convenience init() {
self.init(name: "Tony", age: 18, school: "清华大学")
}
init(name: String, age: Int, school: String) {
self.school = school
super.init(name: name, age: age)
}
}
4. [ ] 重写静态属性
在类中静态属性定义使用 class 或 static 关键字,但是使用哪个要看子类中是否
重写该属性。 class 修饰的属性可以被重写, static 修饰的就不能
class Account {
var account: Double = 0.0 //账号金额
var owner: String = "" //账号名
var interestRate: Double = 0.0668 //利率
// class 不能换成 static
class var staticProp: Double {
return 0.0668 * 1000000
}
var instanceProp: Double {
return self.interestRate * self.amount
}
}
class TermAccount: Account {
//class 换成 static
override class var staticProp: Double {
return 0.0700 * 1000000
}
}
//访问静态属性
print(Acount.staticProp)
print(TermAccount.staticProp)
5. [ ] 重写实例方法
class Person {
...
fun description() -> String {
return "\(name) 年龄是:\(age)"
}
}
class Student: Person {
var school: String
override func description() -> String {
print("父类打印\(super.description())")
return "\(name)年龄是:\(age),所在学校:\(schoo;)。"
}
}
6. 重写静态方法
与类的静态属性定义类似,静态方法使用 class 或 static 关键字,但是使用哪一
个要看子类中是否重写该方法。class 修饰的静态方法可以被重写,static 关键字
的就不能
class Account {
var owner: String = "Tony"//账号名
//不能换成 static
class func interestBy(amount: Double) -> Double {
return 0.08886 * amount
}
}
class TermAccount: Account {//定期账号
//可以换成 static
override class func interestBy(amount: Double)-> Double {
return 0.09 * amount
}
}
7. [ ] 使用 final 关键字
我们可以在类的定义中使用 final 关键字声明类,属性,方法和下标。final 声明
的类不能被继承,final 声明的属性,方法和下标不能被重写。
final class Person {
var name: String
final var age: Int
final func description() -> String {
return "\(name) 年龄时间:\(age)"
}
final class func printClass() ->() {
print("Person 打印...")
}
init(name: String, age: Int) {
self.name = name
self.age = age
}
}
| | <<Class>> | |
| | Person | |
|---------------------------------------------+------------------------------+-----------------------------------------------|
| | var name: String | |
| | var age: Int | |
| | description()->String | |
| | init() | |
| | init(name: String) | |
| | init(name: String, age: Int) | |
|---------------------------------------------+------------------------------+-----------------------------------------------|
| <<Class>> | | <<Clas>> |
| Student | | Worker |
| var school: String | | var factory: String |
| init(name: String,age Int, school: String) | | init(name: String, age, Int, factory: String) |
| | | |
8. [ ] 使用 is 进行类型检查
is 操作符可以判断一个实例是否是某个类的类型。如果实例是目标类型,结果返回
true。否则为 false
let student1 = Student(name: "Tom", age: 18, school: "清华大学")
let student2 = Student(name: "Ben", age: 28, school: "北京大学")
let student3 = Student(name: "Tony", age: 38, school: "香港大学")
let worker = Worker(name: "Tom", age: 18, factory: "钢厂")
let worker2 = Worker(name: "Ben", age: 20, factory: "电厂")
let people = [student1, student2, student3, worker1, worker2]
var studentCount = 0
var workerCount = 0
for item in people {
if item is Worker {
++workerCount
} else if item is Student {
++studentCount
}
}
9. [ ] 类型转换
let p1: Person = Student(name: "Tom", age: 20, school: "清华大学")
let p2: Person = Worker(name: "Tom", age: 18, factory: "钢厂")
let p3: Person = Person(name: "Tom", age: 28)
let p4: Student = Student(name: "Ben", age: 40, school: "清华大学")
let p5: Worker = Worker(name: "Tony", age: 28, factory: "钢厂")
| 对象 | Person类型 | Worker类型 | Student类型 | 说明 |
|------+------------------+------------------+------------------+---------------|
| p1 | 支持 | 不支持 | 支持(向下转型) | 类型:Person |
| | | | | 实例:Student |
| p2 | 支持 | 支持(向下转型) | 不支持 | 类型:Person |
| | | | | 实例:Worker |
| p3 | 支持 | 不支持 | 不支持 | 类型:Person |
| | | | | 实例 Person |
| p4 | 支持(向上转型) | 不支持 | 支持 | 类型:Student |
| | | | | 实例:Student |
| p5 | 支持(向上转型) | 支持 | 不支持 | 类型:Worker |
| | | | | 实例:Worker |
| | | | | |
10. [ ] as 操作符
as 操作符仅仅只应用于向上转型,由于向上转型很少进行,所以在代码中很少能够
看到使用 as 操作符的情况
let p4: Student = Student(name: "Ben", age: 40, school: "清华大学")
let p41: Person = p4 as Person //向上 转型
//将 Student 类型的 p4 转换为 Person 类型是向上转型,向上转型通常可以省略
as Person 部分
11. [ ] as! 操作符
使用 as! 操作符可以应用于如下三种情况:将非可选类型转换为非可选类型,将可
选类型转换为可选类型。示例代码如下:
//向下转型,使用 as!
//1. 将非可选类型转换为非可选类型
let p11 = p1 as! Student
//let p111 = p2 as! Student //编译异常
//2. 将可选类型转换为非可选类型
let p6: Person? = Student(name: "Tom", age: 20, school: "清华大学")
let p12 = p6 as! Student
1. [ ] as? 操作符
使用 as? 操作符可以应用于如下两种情况,将非可选类型转换为可选类型,将可选
类型转换为可选类型
let p6: Person? = Student(name: "Tom", age: 20, school: "清华大学")
......
//向下转型 使用 as?
//1. 将非可选类型转换为可选类型
let p21 = p1 as? Student
let p211 = p2 as? Student //nil
//2. 将可选类型转换为可选类型
let p7: Person? = Student(name: "Tom", age: 20, school: "清华大学")
let p22 = p7 as? Student
2. 使用 AnyObject 和 Any 类型
在 Swift 中还提供了两种类型表示不确定类型: Any 和 AnyObject. AnyObject 可
以表示任何类的类型,而 Any 可以表示任何类型,包括类和其他数据类型,也包括
int 和 Double 等基本数据类型,当然也包括 AnyObject 类型
*** 9. 扩展
1. [ ] 在 Swift 中可以使用一种扩展机制,在原有类型(类,结构体和枚举)的基础上添
加新功能 。扩展是一种"轻量级"的继承机制,即使原有类型被限制继承,我们仍然可以
通过扩展机制 "继承" 原有类型的功能
2. [ ] 声明扩展
extension 类型名 {
//添加新功能
}
声明扩展的关键字是 extension, "类型名"是 Swift 中已有的类型,包括类,结构体和
枚举,但是我们仍然可以拓展整型,浮点型,布尔型,字符串等基本数据类型,这是因
为这些类型本质上也是结构体类型
我们可以在原始类型上扩展计算属性,包括实例计算属性和静态计算属性。这些添加计
算属性的定义,与普通的计算属性的定义一样
extension Int {
var errorMessage: String {
var errorStr = ""
switch(self) {
case -7:
errorStr = "没有数据。"
case -6:
errorStr = "日期没有输入。"
case -5:
errorStr = "内容没有输入"
case -4:
errorStr = "ID 没有输入。"
case -3:
errorStr = "据访问失败。"
case -2:
errorStr = "你的账户最多能插入10条数据"
case -1:
errorStr = "用户不存在,请到51work6.com注册"
default:
errorStr = ""
}
return errorStr
}
}
let messaage = (-7).errorMessage
println("Error code : -7 , Error Messaage:\(message)")
3. [ ] 扩展方法
我们可以在原始类型上扩展,包括实例方法和静态方法。这些添加 方法的 定义和普通
方法的定义是一样的
extension Double {
static var interestRate: Double = 0.668//利率
func interestBy1() --> Double {
return self * Double.interestRate
}
mutating func interestBy2() {
self = self * Double.interestRate
}
static func interestBy3(amount: Double) -> Double {
return interestRate * amount
}
}
let interest1 = (1000.00) * interestBy1()
println("利息1: \(interest1)")
var interest2 = 10000.00
interest2.interestBy2()
println("利息2:\(interest2)")
var interest3 = Double.interestBy3(1000.00)
println("利息3:\(interest3)")
4. [ ] 扩展构造函数
1. [ ] 扩展类型的时候也可以添加新的构造函数
值类型与引用类型扩展有所区别。扩展类的时候能像类中添加新的便利构造函数,但
不能添加新的指定构造函数或析构函数。指定构造函数和析构函数只能有原始类型提
供。
struct Rectangle {
var width: Double
var height: Double
init(width: Double, height: Double) {
self.width = width
self.height = height
}
}
extension Rectangle {
init(length: Double) {
self.init(width: length, height: length)
}
}
var rect = Rectangle(width: 320.0, height: 480.0)
print("长方形:\(rect.width) x \(rect.height)")
var square = Rectangle(length: 500.0)
print("正方形:\(square.width) x (square.height)")
2. [ ] 引用类型扩展构造函数
class Person {
var name: String
var age: Int
func description() -> String {
return "\(name) 年龄是:\(age)"
}
init(name: String, age: Int) {
self.name = name
self.age = age
}
}
extension Person {
convenience init(name: String) {
self.init(name: name, age: 8)
}
}
let p1 = Person(name: "Mary")
print("Person1:\(p1.description())")
let p2 = Person(name: "Tony",age: 28)
print("Person2:\(p2.description())")
*** 10. 协议
1. [ ] 协议概念
| | <<Protocol>> | |
| | Figure | |
|-----------+--------------+-----------|
| | onDraw() | |
|-----------+--------------+-----------|
| <<Class>> | | <<Class>> |
| Rectangle | | Circle |
| | | |
| onDraw | | onDraw() |
| | | |
几何图形这种类在面向对象分析与设计方法学中称为抽象类,方法称为抽象方法。如果
几何图形类中所有的方法都是抽象的,在 Swift 和 Object-C 中我们将这种类称为协议
(Protocol)。
实现抽象方法的过程在 Swift 和 Object-C 中称为遵从协议或实现协议
2. [ ] 协议定义和遵从
protocol 协议名 {
//协议内容,包括:实例属性,静态属性,实例方法和静态方法
}
protocol Figure {
func onDraw() //定义抽象绘制几何图形
}
class Rectangle: Figure {
func onDraw() {
print("绘制矩形")
}
}
class Circle: Figure {
func onDraw() {
print("绘制图形...")
}
}
类型 类型名: 协议1,协议2 {
//遵从协议内容
}
其中类型包括 class struct 和 enum
class 类名: 父类,协议1,协议2 {
//遵从协议内容
}
3. [ ] 协议方法
协议可以要求其遵从者实现某些指定方法,包括实例方法和静态方法
这些方法在协议中被定义,协议方法与普通方法类似,但不支持变长参数和默认值参数,
也不需要大括号和方法体
4. [ ] 协议实例方法
protocol Figure {
func onDraw()//定义抽象绘制几何图形
}
class Rectangle: Figure {
func onDraw() {
println("绘制矩形")
}
}
class Circle: Figure {
func onDraw() {
println("绘制圆形")
}
}
let rect: Figure = Rectangle()
rect.onDraw()
let circle: Figure = Circle()
circle.onDraw()
5. [ ] 协议静态方法
协议中定义静态方法时前面要添加static 关键字
如果遵从者是结构体或枚举,关键就是 static
如果遵从者是类,关键字可以使用 class 或 static,使用 class 遵从者的子类中可以
重写该静态方法,使用 static 遵从者的子类中不可以 重写该静态方法,这个规则与子
类继承父类的规则一样
protocol Account {
static func interestBy(amount: Double) -> Double
}
class ClasImp: Account {
class func interestBy(amount: Double) -> Double {
return 0.0668 * amount
}
}
struct StructImp: Account {
static func interestBy(account: Double) -> Double {
return 0.0668 * amount
}
}
enum EnumImp: Account {
static func interestBy(amount: Double) -> Double {
return 0.0668 * amount
}
}
6. [ ] 协议属性
1. 无论是存储属性还是计算属性,只要能满足协议属性的要求,就可以通过编译,甚至
是协议中只规定了只读属性,而遵从者提供了对该属性的读写实现,这也是被允许的,
因为遵从者满足了协议的只读属性要求。协议只规定了遵从者必须要做的事情,但没
有规定不能做的事情。
protocol Person {
var firstName: String{ get set}
var lastName: String{get set}
var fullName: String{get}
}
class Employee: Person {
var no: Int = 0
var job: String?
var salary: Double = 0
var firstName: String = "Tony"
var lastName: String = "Guan"
var fullName: String {
get {
return self.firstName + "." + self.lastName
}
set (newFullName) {
var name = newFullName.componentsSeparatedByString(".")
self.firstName = name[0]
self.lastName = name[1]
}
}
}
7. [ ] 协议静态属性
协议中定义静态属性前面要添加 static 关键字
如果遵从者是结构体或枚举,关键字就是 static
如果遵从者是类,关键字可以使用 class 或 static ,使用 class 遵从者的子类中可以
重写该静态属性,使用 static 遵从者的子类中不可以重写该静态属性,这个规则与子
类继承父类的规则一样
协议静态方法
protocol Account {
class var interestRate: Double {
class func interestBy(amount: Double) -> Double
}
class ClassImp: Account {
class var interestRate: Double {
return 0.0668
}
class func interestBy(amount: Double) -> Double {
return ClassImp.interestRate * amount
}
}
struct StructImp: Account {
static var interestRate: Double = 0.668
static func interestBy(amount: Double) -> Double {
return StructImp.interestRate * amount
}
}
enum EnumImp: Account {
static var interestRate: Double = 0.668
static func interestBy(amount: Double) -> Double {
return EnumImp.interestRate * amount
}
}
** 3. IOS 应用开发概述
1. [ ] HelloiOS 工程
1. [ ] Product Name: 工程名字
2. [ ] Team: 在苹果 App Store 开发者名字,没有可以为 None
3. [ ] Organization Name: 组织名称,可以是团队,机构或开发者名字
4. [ ] Organization Identifier:组织标识(很重要)。一般情况下,这里输入的是
团队,机构或开发的域名(如com.51work6),这类似于 Java 中的包命名
5. [ ] Bundle Identifier: 捆绑标识符(很重要)。该标识符由 Product Name +
Organization Identifier 构成。因为在 App Store 上发布应用时会用到它,所以
它的命名不可重复
6. [ ] Language: 开发语言选择。这里可以选择开发应用所使用的语言,在 Xcode 6
之后可以选择 Swift 或 Objective-C
7. [ ] Devices: 选择设备。可以构建基于 Iphone 或 Ipad 的工程,也可以构建通用
工程。通用工程在 Iphone 和 IPad上都可以正常运行
8. [ ] Use Core Data: 选中该选项,可以在工程中添加 Core Data 代码。Core Data
是苹果的数据持久化技术
9. [ ] Include Unit Tests: 选中该选项,可以在工程中添加单元测试代码
10. [ ] Include UI Tests: 选中该选项,可以在工程中添加 UI 测试代码
2. [ ] Xcode 中的 IOS 工程模板
1. [ ] Application 类型
1. [ ] Single View Application: 可以构建简单的单个视图应用
2. [ ] Game: 可以构建基于 IOS 的游戏应用
3. [ ] Master-Detail Application: 可以构建树形结构导航模式应用,生成的代码
中包含了导航控制器和表视图控制器等。
4. [ ] Page-Based Application: 可以构建类似于电子书效果的应用,这是一种平
铺导航
5. [ ] Tabbed Application: 可以构建标签导航模式的应用,生成的代码中包含了
标签控制器和标签栏等
6. [ ] Sticker Pack Application: 可以构建表情包 (Sticker Pack) 应用。
7. [ ] iMessage Application: 可以构建聊天应用
2. [ ] Framework & Library 类型
1. [ ] Cocoa Touch Framework: 可以让开发者自定义应用于 IOS 的框架。
2. [ ] Cocoa Touch Static Library: 可以让开发者创建基于 Foundation 框架的
静态库。出于代码安全和多个工程重用代码的考虑,可以将一些类或函数编写成
静态库。静态库不能独立运行,编译成功时会生成名为 libxxx.a 的文件(例如:
libHelloWorld.a)
3. [ ] Metal Library: 可以让开发者自定义应用于 Metal 库
3. [ ] HelloiOS 中的类图
1. [ ]
| AppDelegate | UIResponser | UIViewController |
|-----------------------+-------------+------------------|
| | | |
| | | |
| <<Delegate>> | | ViewControler |
| UIApplicationDelegate | | |
| | | |
import UIKit
@UIApplicationMain
class AppDelegate: UIResponse, UIApplicationDelegate {
var window: UIWindow?
fun application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions:
[UIApplicationLaunchOptionsKey: Any]?) -> Bool {
return true
}
func applicationWillResignActive(_ application: UIApplication) {
}
func applicationDidEnterBackground(_ application: UIApplication){
}
func applicationWillEnterForeground(_ application: UIApplication) {
}
func applicationDidBecomeActive(_ application: UIApplication){}
func applicationWillTerminate(_ application: UIApplication) {}
}
2. [ ] 应用生命周期
| not Running |
|-------------|
| Inactive |
| |
| Active |
| |
| Background |
| |
| suspend |
1. [ ] Not Running (非运行状态):应用没有运行或被系统终止
2. [ ] Inactive (前台非活动状态):应用正在进入前台状态,但是还不能接受事件
处理 。
3. [ ] Active(前台活动状态): 应用进入前台状态,能接受事件处理。
4. [ ] Background(后台状态): 应用进入后台后,依然能够执行代码。
如果有可执行的代码,就会执行代码,如果没有可执行的代码或者将可执行的代
码执行完毕,应用汇马上进入挂起状态。
5. [ ] Suspend(挂起状态): 处于挂起状态的应用进入一种 “冷冻” 状态,不能
执行代码。如果系统内存不够,应用会被终止。
| 方法 | 本地通知 | 说明 |
|------------------------------------+----------------------------------------------------+----------------------------------------------------------------------------------------------------|
| applicationDidFinishLaunching(_:) | Notification.Name | 应用启动并进行初始化时,会调用该方法并发出通知。这个阶段会实例化根视图控制器 |
| | UIApplicationDidFinishLaunching | |
| | | |
| | | |
| applicationDidBecomeActive(_:) | Notification.Name.UIApplicationDidBecomeActive | 应用进入前台并处于活动状态时调用该方法并发出通知。这个阶段可以恢复UI的状态(例如游戏状态等) |
| | | |
| | | |
| | | |
| | | |
| | Notification.Name.UIApplicationWillResignActive | 应用从活动状态进入到非活动状态时调用该方法并发出通知。这个阶段可以保存UI的状态(例如游戏状态等) |
| applicationWillResignActive(_:) | | |
| | | |
|------------------------------------+----------------------------------------------------+----------------------------------------------------------------------------------------------------|
| applicationDidEnterBackground(_:) | Notification.Name.UIApplicationDidEnterBackground | 应用进入后台时调用该方法并发出通知。这个阶段可以保存用户数据,释放一些资源(例如释放数据库资源等) |
| | | |
| | | |
| | | |
| | | |
| | | |
| applicationWillEnterForeground(_:) | Notification.Name.UIApplicationWillEnterForeground | 应用进入后台时调用该方法并发出通知。这个阶段可以恢复用户数据 |
| | | |
| | | |
| | | |
| applicationWillTerminate(_:) | NOtification.Name.UIapplicationWillTerminate | 应用被终止时调用该方法并发出通知,但内存清除时除外。这个阶段释放一些资源,也可以保存用户数据 |
| | | |
4. [ ] iOS API 简介
1. [ ] iOS 整体架构图
| Cocoa Touch |
|---------------|
| Media |
| Core Services |
| Core OS |
2. [ ] Cocoa Touch 层包括的框架
| 框架 | 前缀 | 说明 |
|-----------------+------+-----------------------------------|
| Address Book UI | AB | 访问用户的联系人信息 |
| Event Kit UI | EK | 访问用户的日历事件数据 |
| Game Kit | GK | 提供能够进行点对点的网络通信的API |
| iAd | AD | 在应用中嵌入广告 |
| Map Kit | MK | 在应用中嵌入地图和地理信息编码等 |
| Message UI | MF | 提供与发送 E-email 相关的 API |
| PhotosUI | PH | 照片 UI 相关的 API |
| Twitter | TW | 提供发送 Twitter 的接口 |
| UIKit | UI | 提供 UI了类 |
3. [ ] Media 层包括的框架
| 框架 | 前缀 | 说明 |
|-----------------+-----------+----------------------------------------------------------------------|
| AssetsLibrary | AL | 提供访问用户的图片和视频的接口 |
| AadioToolBox | Audio | 录制或播放视频,音频流以及转换 |
| AadioUnit | Audio, AU | 可以使用内置音频单元服务及音频单元模块 |
| AV Foundation | AV | 提供播放与录制音频和视频的 Objective-C 接口 |
| Core Foundation | Audio | 提供录制,制作,播放音频的 C 语言接口 |
| Core Graphics | CG | 提供 Quzrtz.ZD 接口 |
| Core Image | CI | 提供操作视频和静态图像的接口 |
| Core MIDI | MIDI | 提供用于处理 MIDI 数据底层的 API |
| Core Text | CT | 提供渲染文本和处理文字的简单,高效的 C 语言接口 |
| Core Video | CV | 提供用于处理音频和视频的 API |
| Image I/O | CG | 包含一些读写图像数据类 |
| GLKit | GLK | 包含了构建复杂 OpenGL ES 应用的 Objective-C 实用类 |
| Media Player | MP | 包含全屏播放接口 |
| OpenAL | AL | 包含了OpenAL(跨平台的音频) 的 C 语言接口 |
| OpenGL ES | EAGL, GL | 包含了 OpenGL ES(跨平台的 2D/3D 图像库)的 C 语言接口提供动画接口类 |
| Quartz Coroe | CS | 提供动画接口类 |
| Sprite Kit | SK | 苹果提供的基于 2D 游戏的开发引擎,可以开发 IOS 和 macOS 的游戏 |
| Scene Kit | SCN | 一种高级别 3D 图形框架,能够帮助在 APP 中创建 3D 动画场景和特效 |
| | | |
4. [ ] Core Services 层包括的框架
| 框架 | 前缀 | 说明 |
|--------------------------+------+-----------------------------------------------------------------------------------------------------------------------|
| Accounts | AC | 用于访问用户的 Twitter 账户(iOS5 之后才有此 API |
| AddressBook | AB | 访问用户的联系人信息 |
| AdSupport | AS | 获得 iAD 广告标识 |
| CFNetwork | CF | 提供了访问 WIFI 网络和蜂窝电话网络的 API |
| Core Data | NS | 提供管理应用数据的 ORM 接口 |
| CoreFoundation | CF | IOS 开发中最基本的框架,包括数据集 |
| Core Location | CL | 提供定位服务的 API |
| CoreMedia | CM | 提供 AV Foundation 框架使用的底层媒体类型,可以精确控制音频或视频的创建及展示 |
| CoreMotion | CM | 接收和处理重力加速计及其他的运动事件 |
| CoreTelephon | CT | 提供访问电话基本信息的 API |
| Event Kit | EK | 访问用户的日历事件数据 |
| Foundation | NS | 为 Core Foundation 框架的许多功能提供 Objective-C 封装,是 Objective-C 最为基本的框架 |
| JavaScriptCore.framework | JS | 提供了基于 Objective-C 语言封装的标准 JavaScript 对象,通过该框架可以实现 Objective-C 与 JavaScript 之间的相互调用 |
| MobileCoreServices | UT | 定义统一类型标识符(UTI)使用的底层类型 |
| Newsstand Kit | NK | 提供在后台下载杂志和新闻的 API 接口(iOS6 之后才有此 API) |
| Pass Kit | PK | 提供访问各种优惠券的 API(iOS6 之后才有此 API) |
| QuickLook | QL | 该框架可以预览无法直接查看的文件内容,例如打开 PDF 文件 |
| Social | SL | 提供社交网络访问 API,中国区提供新浪微博API(iOS6 之后才有此 API) |
| Store Kit | SL | 提供内置收费的薪金交易 |
| SystemConfiguration | SC | 用于确定设备的网络配置。例如,使用该框架判断 WI-FI 或者蜂窝连接是否正在使用中,也可以用于判断某个主机服务是否可以使用 |
| Cloud Kit | CK | 开发 ICloud 应用的新型 API |
| Health Kit | HK | 开发健康和健身等服务的 API ,在一个位置上访问共享的健康相关的信息 |
| Home Kit | HM | 能够与用户家中连接的设备信息并进行控制 |
| | | |
5. [ ] Core OS 层包括的框架
| 框架 | 前缀 | 说明 |
|---------------------------+----------+------------------------------------------|
| Accelerate | AC | 访问重力加速计 API |
| Core Bluetooth | CB | 访问低能耗蓝牙设备 API |
| External Accessory | EA | 访问外围配件 API 接口 |
| Generic Security Servcies | gss | 提供一组安全相关的服务 |
| Security | CSSM,Sec | 管理证书,公钥,私钥和安全信任策略的 API |
| LocalAuthentication | LA | 通过用户指定的安全策略进行安全 认证 |
| | | |
5. [ ] 如何使用 API 帮助
1. [ ]
import UIKit
class ViewControler: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
6. [ ]
** 4. IOS 应用界面技术
*** 1. 界面构建技术
1. [ ] 使用故事板
1. [ ] 故事板的导航特点
2. [ ] 故事板中的 Scene 和 Segue
Scene 和 Segue 是故事板中非常重要的两个概念。每个视图控制器都会对应一个
Scene(译为“场景”),可以理解为应用的一个界面或屏幕。这些 Scene 之间通过
Segue 连接,Segue 不但定义了 Scene 之间的导航(或跳转)方式,还体现了
Scene 之间的关系。Scene 的类型分为: Push,Modal, Popover 和自定义方式,
Scene 要与具体的控制器结合使用,Push 是树形导航模式;Modal 是模态导航模式;
Popover 是呈现浮动窗口
3. [ ] 使用 xlib 文件
Xib 和故事板比较
| | |
|--------------------------+------------------------|
| AppDelegate.h | AppDelegate.h |
| AppDelegate.m | AppDelegate.m |
| FirstViewController.h | FirstViewController.h |
| FirstViewController.m | FirstViewController.m |
| SecondViewController.h | SecondViewController.h |
| SecondViewController.m | SecondViewController.m |
| FirstViewController.xib | Main.storyboard |
| SecondViewController.xib | |
| | |
4. [ ] 使用代码
代码是万能的,通过代码完全可以构建应用层面,但是调试起来非常的麻烦。每次的
界面的修改结果,只能重新运行才能看到,不是“所见即所得”的,这是最大的问题。
三种构建界面技术,故事板和 Xib 都属于 “所见即所得”技术,此外故事板还可以表
述界面之间的导航,而 Xib 只能设计单个界面。由于一个工程只有一个故事板,当
进行团队开发时候,多人修改界面时候,如果管理的不好就会发生冲突,而故事板这不
会出现这个问题,另外考虑屏幕适配问题的时候 ,故事板和 Xib 设计起来比较麻烦,
不如代码实现灵活。
*** 2. MVC 模式
1. [ ] 模型:保存应用数据的状态,回应视图对状态的查询,处理应用业务逻辑,完成应
用的功能,将状态的变化通知视图。
视图: 为用户展示信息并提供接口。用户通过视图向控制器发出动作请求,然后再向模
型发出查询状态的申请,而模型状态的变化会通知给视图
控制器:接收用户的请求,根据请求更新模型。另外,控制器还会更新所选择的视图作
为对用户请求的回应。控制器是视图和模型的媒介,可以降低视图与模型的耦合度,使
视图和模型的权责更加清晰,从而提高 开发效率。
2. [ ] Cocoa Touch MVC 模式
Cocoa Touch 框架中的 MVC 模式与传统模式略有不同,前者的模型与视图不能进行任何
通信,所有的通信都是通过控制器完成
3. [ ] 视图控制器
1. [ ] UIViewController: 用于自定义视图控制器的导航。例如,对于两个界面的跳转,
可以用一个 UIViewController 来控制另外两个 UIViewControlller
2. [ ] UINavigationController: 导航控制器,它与 UITableViewController 结合使
用,能够构建树形结构导航模式
3. [ ] UITabBarController: 标签栏控制器,用于构建树标签导航模式。
4. [ ] UIPageViewController: 呈现电子书导航风格的控制器。
5. [ ] UISplitViewController: 可以把屏幕分割成几块的视图控制器,主要为 iPad
屏幕设计。
6. [ ] UIPopoverController: 呈现“气泡”风格视图的控制器,主要为 iPad 屏幕设计
4. [ ] 视图控制器生命周期
| 视图 | 视图控制器 |
|------------+--------------------------------|
| 视图创建 | 调用 viewDidLoad 方法 |
| | |
| | 调用 viewWillAppear(_:) 方法 |
| 视图可见 | |
| | 调用viewDidAppear(_:) 放法 |
| | |
| | 调用 viewWillDisappear(_:)方法 |
| 视图不可见 | |
| | 调用 viewDidDisappear(_:) 方法 |
*** 3. 视图与 UIView
1. [ ] UIView 继承层次结构
1. [ ] 从继承关系上看,UIView 是所有视图的“根”,这就构成如图5-8 所示的
UIView 类的继承层次
| | | | | |
|--------+------+-------------------------+------+--------------------|
| | | UIWindow | | |
| | | | | |
| | | UILabel | | |
| | | | | |
| | | UITableViewCell | | |
| | | | | UITableView |
| | | UIScrollView | <--- | UI TextView |
| | | | | UICollectView |
| | | UIPickerView | | |
| | | | | |
| | | UIProgressView | | |
| | | | | |
| UIView | <--- | UIActivityIndicatorView | | |
| | | | | |
| | | UIImageView | | |
| | | | | |
| | | UITabBar | | |
| | | | | UIButton |
| | | UIToolbar | | UIDatePicker |
| | | | | UIPageControl |
| | | UIControl | <--- | UISegmentedControl |
| | | | | UITextField |
| | | UINavigationBar | | UISlider |
| | | | | UISwitch |
| | | UIActionSheet | | |
| | | | | |
| | | UIAlertView | | |
| | | | | |
| | | UIWebView | | |
| | | | | |
*** 4. 视图分类
1. [ ] 视图分类
1. 控件:继承 UIControl 类,能够响应用户高级事件
2. 窗口:它是 UIWindow 对象。一个 IOS 应用只有一个 UIWindow 对象,它是所有子
视图的 ”根“ 容器。
3. 容器视图:它包括了 UIScrollView ,UIToolbar 及他们的子类。UIScrollView 的子
类有 UITextView, UITableView 和 UICollectionView, 在内容超出屏幕时,他们可
以提供水平或垂直滚动条。
UIToolbar 是非常特殊的容器,它能够包含其他控件,一般置于屏幕底部,特殊情况
下也可以置于屏幕顶部。
4. 显示视图:用于显示信息,包括 UIImageView, UILabel,UIProgressView 和
UIActivityIndicatoryView 等
5. 文本和 web视图:提供了能够显示多行文本的视图,包括 UITextView 和
UIWebView,其中 UITextView 也属于容器视图,UIWebView 是能够加载和显示 HTML
代码的视图
6. 导航视图:为用户提供从一个屏幕到另外一个屏幕的导航 (或跳转)视图。它包括
UITabBar 和 UINavigationBar
7. 警告框 和操作表:用于给用户提供一种反馈或者与用户进行交互。UIAlertView 视
图是一个警告框,它会以动画形式弹出来;而 UIActionSheet 视图给用户提供可选
的操作,它会从屏幕底部滑
2. [ ] 应用界面的构建层次(27)
1. UIWindwo --> UIView(RootView) --> UIView(View2)
2. superview: 获取父视图对象
subviews: 获得子视图集合
window:获得视图所在的 UIWindow 对象
3. [ ] 控件与动作事件
1. [ ] 按钮 (Type 属性)
Custom: 自定义类型。如果不喜欢圆角 按钮,可以使用该类型
System:系统默认属性,表示该按钮没有边框,在 IOS 7 之前按钮默认为圆角矩形
Detail Disclosure: 细节展示按钮 ,主要用于表示视图中的细节展示
Info Light 和 Info DarK:这两个是信息按钮,样式上与细节展示按钮一样,表示
有一些信息需要展示,或有可以设置的内容
Add Contact: 添加联系人按钮
2. [ ] 按钮(State Config属性)
Defualt
Highlighted
Selected
Dishabled
4. [ ] 定义动作事件
ViewControler
@IBAction func onClick(sender: AnyObject) {
...
}
Xib 文件或者故事板文件
View(标签,按钮)
5. [ ] 视图与输出口
6. [ ]
*** 5.
*** 6.
** 5.