这是我参与「第四届青训营 -iOS场」笔记创作活动的的第4篇笔记
UIKit
UIApplication
- app入口
int main(int argc, char * argv[]) {
NSString * appDelegateClassName;
@autoreleasepool {
// Setup code that might create autoreleased objects goes here.
appDelegateClassName = NSStringFromClass([AppDelegate class]);
}
return UIApplicationMain(argc, argv, nil, appDelegateClassName);
}
- 单例模式,一个应用程序只会有一个
- 应用实例,负责监听应用级时间
- AppDelegate,应用级时间代理,管理应用程序的生命周期、通知事件、外部调用
在发生不同事件,调用不同的回调方法
App生命周期
- Not Running,未运行
- Inactive,前台非活动状态,处于前台,但是不能接受事件处理
- Active,前台活动状态,能接受事件处理
- Background,后台状态,如果有可执行代码就进行执行,否则挂起
- Suspended,挂起状态,如果内存不足,会被杀死
视图
- UIKit,提供基础视图类库
- UIView,所有视图的根类
- 实际上是CALayer的封装
- UIView,处理布局和触摸事件;CALayer,负责绘图、动画、变化
- 为了职责分离,但是UIView灵活性差,需要进入CALayer层进行处理
- UIViewController,所有视图控制器的基类,负责视图显示、界面跳转
- 生命周期 init -> loadView -> viweDidLoad -> viewWillAppear -> viewDidAppear -> 开始退出 -> viewWillDisappear -> viewDidDisappear -> viewWillUnload -> viewDidUnload -> dealloc
- init进行数据初始化,不要出现创建view
- loadView进行view创建和初始化
- viweDidLoad,附加的view和空间
- viewWillAppear,显示前处理,键盘弹出或特殊动画
- viewDidAppear,显示动画后的操作
图形几何学
- UIView重要属性,frame,bounds,center,只是一个存取的接口,最终是改变CALayer的frame、bounds、position
- frame,外框的界面大小
- bounds,长宽
- center,中心
- 锚点,图形移动的中心点/把柄
- 坐标系,一个图层的position依赖于父图层,相对于父图层建立的直角坐标系
- 布局,设置(x, y, height, width),放在界面上
- 自动布局,关心视图之间的约束,多个视图之间的相对位置
- masonry/snapkit
- zPosition,前后位置,只是将绘制顺序放在最上方,实际的view层还是在下方,那么实际上触摸的还是根据add顺序,需要调用
bringSubviewToFront
- 仿射变化,利用transform属性,再二维空间做旋转、缩放、平移
- 3D变化,使用矩阵的各个元素进行变化,增加对z轴的变化
- 视觉效果,圆角、边框、阴影,修改layer的属性;阴影会影响子视图,边框不会
- cornerRadius
- borderWidth
- shadow
Swift
优势
- nil值
- OC,nil代表空对象的指针
- swift,有optional的概念,如果是nil,不会进行任何处理
- 类型安全
- OC 隐氏转换,会导致精度缺失
- swift 显氏转换,在类型转换时需要指出
- 运行快
基础知识
- 变量定义,存在类型自动推断
// 不可变
let a = 10
// 可变
var b = 20
// 数组
var names: [String] = ["Tom"]
// 字典
var classes: [String : String] = ["class" : "Tom"]
// 合集,无序set
var id: Set<String> = ["1", "2", "3"]
- 可选值
var name: String?
- 循环
for idx in 0..<10 {}
while(condition) {}
- 函数
// inout 表示参数传递为引用传递,调用时传入地址
// 参数前面加 _,表示参数名可以省略
func funcName(argName: aryType, ...) -> returnType {code...}
- 类
class ClassName: FatherClass {}
- 类的扩展,增加方法
extension ClassName {}
- 协议
protocol ProrocalName: NSObjectProtocal {}
// 定义变量
var name: String {get set}
// 定义函数,不用实现
func funcName(argName: aryType, ...) -> returnType
- 协议修饰
- mutating,该方法可以改变协议中的变量
- required,实现指定初始化器,满足协议的初始化要求,子类必须要实现
- required & override,父类和协议有相同的构造器,且父类的构造器没有用required修饰,那么重写的子类构造器就要使用required override修饰;如果子类带final,就不需要用required,final表示不会被任何类继承,也就不会有子类是否需要继承的问题
- 泛型
// 函数
func swap<T>(_ a: **inout** T, _ b: **inout** T) {
let temp = a
a = b
b = temp
}
// 类
class ClassName<Element> {}
- 闭包
- 利用上下文推断形式参数和返回值类型 {(s1: String, s2: String) -> Bool in} -> {s1, s2 in return s1 > s2}
- 单表达式闭包隐式返回 {arg1, arg2 in arg1 > arg2} 类似java的lmabda表达式,闭包中只有单条语句,直接写
- 简写实际参数名 {arg1, arg2 in arg1 > arg2} -> {1}
- 简写实际参数名 {1} -> ( > )
- 尾随闭包,作为函数参数值传递,需要写在函数参数列表外边
var block: (argType, ...) -> returnType = {arg... in
//code...
return ...
}
// 简写
var block: (String) -> String = {
print($0)
return $0 + "1232"
}
// sort
let s1 = Student(name: "Tom", score: 300)
let s2 = Student(name: "Anna", score: 100)
let s3 = Student(name: "Aana", score: 100)
var students = [s2, s1, s3]
students = students.sorted {
if $0.score != $1.score {
// 大于降序
return $0.score > $1.score
}
// 小于升序
return $0.name < $1.name
}
swfitUI
- 只是一个工程形式,与storyboard是平级的
- contentView,管理页面布局
- PreviewProvider,声明视图预览
- 手动设置样式
栈视图
- 三种布局形式
// 垂直
VStack {
}
// 水平
HStack {
}
// 覆盖布局
ZStack {
}
- 嵌套布局
VStack {
Text("Hello, world!")
.padding()
HStack {
Text("Hello, world!")
.font(.headline)
.foregroundColor(Color.red)
.padding()
Text("Hello, world!")
.padding()
}
}
Button
struct CaseView: View {
@State var change = false
var body: some View {
VStack {
Text(change ? "欢迎关注" : "下次再来")
.padding()
Button {
// 取反change
self.change.toggle()
} label: {
Text("button")
.padding()
}
}
}
}
页面push跳转
- 第一个页面
struct ContentView: View {
var body: some View {
NavigationView() {
VStack {
Text("Hello, world!")
.padding()
HStack {
Text("Hello, world!")
.font(.headline)
.foregroundColor(Color.red)
.padding()
Text("Hello, world!")
.padding()
}
NavigationLink(destination: NextView()) {
Text("go to next")
.foregroundColor(.yellow)
}
}
}
}
}