第一节_基本知识
Mac和Xcode一些快捷键
command键:win键,option键:alt键
复制:com+c,粘贴:com+v,剪切:com+x
保存:com+s,撤销:com+z
运行程序:com+r
注释、取消注释:com+/
单步运行:F6
数据类型
- 共有数值类型、字符串类型、布尔类型、枚举类型、合集类型五种
- Swift中不强制要求定义类型,强制定义的只有常量let、变量var,let常量初始化后即不能再更改值
数值类型
有int、uint(无符号整数)、float、double四种基本数值类型1
2
3let n = 70
let m = 50.0 //等号两边空格数必须相等
var n:Double = 50 //显示定义的类型
字符串类型
1 | 格式化字符串 |
计算字符串长度:str2.count
比较字符串是否相等:== 和 !=
在Swift中字符串是值类型,复制传递的是字符串的值而非引用
布尔类型(Bool)
true/false
枚举类型
1 | enum DaysOfWeek{ //定义枚举类型 |
合集类型(Collection)
- 数组和区间
- 字典(dict):键值对
- 集合(set):无序、不重复数组
三种类型都可用xx.count表示元素数量1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18//数组
var an1 = [1,2,3,4]
var an2 : [Int]
an2 = [1,2,3,4]
//区间
an1[1..<3] //an[1],an[2]
an1[1...3] //an[1],an[2],an[3]
//字典
var dic: [String : Int]
dic = ["Red":0,"Green":1,"Bule":2]
dic["Red"] //0
//集合
let s1 = Set([1,2,3])
let s2 : Set<Int>
s2 = [1,2,3]
可选值Optional
类型后加?为可选值,代表声明的变量可能为空(nil)1
2
3
4
5
6
7
8
9
10let dic = [0:"Red",1:"Blue",2:"Yellow"]
var color = dic[0] //color为String?类型,可能会返回nil值
print(color) //输出Optional("Red"),对"Red"封包了
if color! = nil{ //color不为空才执行操作
let actualColor = color! //对Optional("Red")拆包
}
else{
//统一在拆包阶段对nil进行处理,逻辑更清晰
}
第二节_语句
for-in循环
1 | for index in 1...5{ |
switch-case
1 | //没有break |
函数
1 | 函数定义 |
第三节_IOS开发
MVC模式
Model-View-Controller(模型-视图-控制器),面向对象的常用模式
模型:保存数据的类
视图:UI控件
控制器:把模型和控制器绑定在一起的类,以及实现中间逻辑层。
优点:可最大限度地分离这三类代码(数据、UI、逻辑),每个类只实现专一的功能。
控制类的绑定
1 | 输出接口: |
网络传输(HTTP协议)
HTTP协议分为请求头和数据部分,请求头系统有内置属性,后台也是tomact服务器会自动处理
数据部分则是和后台自己约定的,比如提交到哪个文件夹,提交的文件叫什么名字等等。
1 | //先把HTTP数据部分写好(Data形式),方便后面传入request中 |
多线程操作
在GUI中,默认操作都是在主线程中完成的(对控件的操作,以及与控件无关的操作),因此如果有非常耗时的操作,就需要另开一个线程,放在其中执行,否则耗时的操作会使主线程阻塞,导致UI界面无法操作(点击按钮、输入文本等)。
而在分线程中,如果涉及到对UI界面的操作,就要再手动回到主线程中去操作相应控件,在swift中对应为DispatchQueue.main.async {//code}
。
swift中的线程操作,可通过GCD(Grand Central Dispatch)的方式完成,其将代码以队列(先进先出)的形式放入其他线程中执行。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15//...code1
let queue = DispatchQueue.global(qos:.default)
queue.async {
//code3
DispatchQueue.main.async {
//在分线程中回到主线成中操作UI
upImgButton.isEnabled = false
}
}
//...code2
//代码说明:
//code1执行完后,建立线程队列queue,系统将块内的代码放入队列中,但并不会立即执行
//之后会执行code2,等当前线程时间片到了,才会去执行queue线程中的代码
//若没有并行设置,queue线程中的代码默认是顺序执行的
IOS图像格式
关于IOS的图像系统,有三种格式
- UIImage:在UIKit框架下显示的图像格式,用于UI显示,通过UIImageView.image调用或赋值
- CIImage:CoreImage框架操作的图像格式,CI框架的函数都是针对这个数据格式
- CGImage:位图格式,底层的图像存储格式,UI和CI本质都是对CGImage的封装
1 | //三种图像的互相转换,UI和CI图像的转换都是通过CG间接完成的 |
人脸识别(系统库)
参考博文:https://www.jianshu.com/p/e371099f12bd1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119//IOS内置的图像处理库,用于处理一些复杂的图像操作
import CoreImage
//人脸识别函数的传入参数之一
let imageOptions = NSDictionary(object: NSNumber(value: 5) as NSNumber, forKey: CIDetectorImageOrientation as NSString)
//未识别的原始照片
let personciImage = CIImage(cgImage: imageView.image!.cgImage!)
//定义精确度,High为较高的精度
let accuracy = [CIDetectorAccuracy: CIDetectorAccuracyHigh]
//定义人脸识别器
let faceDetector = CIDetector(ofType: CIDetectorTypeFace, context: nil, options: accuracy)
//识别人脸,返回人脸数组
let faces = faceDetector?.features(in: personciImage, options: imageOptions as? [String : AnyObject])
//因为UI和CI两大框架的坐标系原点不相同
//UI为左上角,CI为左下角,因此要进行坐标变化
//否则人脸的位置坐标不对
let ciImageSize = personciImage.extent.size
//改变x,y延伸方向
var transform = CGAffineTransform(scaleX: 1, y: -1)
//改变原点位置
transform = transform.translatedBy(x: 0, y: -ciImageSize.height)
if let face = faces?.first as? CIFaceFeature {
//进行坐标系变换
//face.bounds返回识别的人脸CRect框,包括起点位置和图像宽、高
let faceImgBounds = face.bounds.applying(transform)
let sourceImageRef: CGImage = imageView.image!.cgImage!
//根据Rect截取人脸
let newCGImage = sourceImageRef.cropping(to: faceImgBounds)
var tempImage = UIImage.init(cgImage: newCGImage!)
//对截取的人脸图像进行压缩
let tempCGSize = CGSize(width:tempImage.size.width/4,height:tempImage.size.height/4)
UIGraphicsBeginImageContext(tempCGSize)
tempImage.draw(in: CGRect(x: 0, y: 0, width: tempCGSize.width, height: tempCGSize.height))
//因为图像会有向左旋转90度的bug,因此要进行修正
tempImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
tempImage = tempImage.fixOrientation()
//写入ImageView中
faceImg.image = tempImage
}
else {
let alert = UIAlertController(title: "提示", message: "未检测到人脸", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "确定", style: UIAlertActionStyle.default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
// 修复图片旋转代码,扩展UIImage类
//根据图像的imageOrientation属性值来进行旋转
extension UIImage {
func fixOrientation() -> UIImage {
// if self.imageOrientation == .up {
// return self
// }
var transform = CGAffineTransform.identity
switch self.imageOrientation {
case .down, .downMirrored:
transform = transform.translatedBy(x: self.size.width, y: self.size.height)
transform = transform.rotated(by: .pi)
break
case .left, .leftMirrored:
transform = transform.translatedBy(x: self.size.width, y: 0)
transform = transform.rotated(by: .pi / 2)
break
case .right, .rightMirrored,.up:
transform = transform.translatedBy(x: 0, y: self.size.height)
transform = transform.rotated(by: -.pi / 2)
break
default:
break
}
switch self.imageOrientation {
case .upMirrored, .downMirrored:
transform = transform.translatedBy(x: self.size.width, y: 0)
transform = transform.scaledBy(x: -1, y: 1)
break
case .leftMirrored, .rightMirrored:
transform = transform.translatedBy(x: self.size.height, y: 0);
transform = transform.scaledBy(x: -1, y: 1)
break
default:
break
}
let ctx = CGContext(data: nil, width: Int(self.size.width), height: Int(self.size.height), bitsPerComponent: self.cgImage!.bitsPerComponent, bytesPerRow: 0, space: self.cgImage!.colorSpace!, bitmapInfo: self.cgImage!.bitmapInfo.rawValue)
ctx?.concatenate(transform)
switch self.imageOrientation {
case .left, .leftMirrored, .right, .rightMirrored:
ctx?.draw(self.cgImage!, in: CGRect(x: CGFloat(0), y: CGFloat(0), width: CGFloat(size.height), height: CGFloat(size.width)))
break
default:
ctx?.draw(self.cgImage!, in: CGRect(x: CGFloat(0), y: CGFloat(0), width: CGFloat(size.width), height: CGFloat(size.height)))
break
}
let cgimg: CGImage = (ctx?.makeImage())!
let img = UIImage(cgImage: cgimg)
return img
}
}
Post Date: 2018-01-27
版权声明: 本文为原创文章,转载请注明出处