1
- 指令式编程 imperative,C、C++,写给计算机的语言
- 声明式编程 declarative,用DSL或函数式编程实现,函数式编程用 reduce、map、sorted 等,写给人看的语言
- DSL Domain-Specific Language 领域特定语言,代表SQL
- Combine 响应式编程框架 ,处理数据流
- FRP Functional reactive programming 函数响应式编程
- 枚举遵从 CaseIterable 协议,有allCases 属性,返回所有枚举类型组成的数组
- 元组取下标,用的是点语法,temp.1
- reduce(0, +) ,数组取第一个 .first
- 声明式UI起源Elm语言,后继者 React的Component、Flutter的Widget
- Redux、Flux 思想来源 Elm,状态管理和组件通信架构,Store、State、Action。在大中型项目中应用可以,小项目应用由于其引入的复杂度会得不偿失。
- SwiftUI 和 UIKit 可以兼容使用
2
- 刷新预览的快捷键是 Option + Command + P
- Text 有属性 font,foregroundColor,padding、background,.minimumScaleFactor(0.5)缩放系数 .lineLimit(1) 限制一行,传入nil不限制。foregroundColor 可以设置.primary 能自适应亮暗模式。
- 字体还有 .headline,.body 等,按数值指定 .font(.system(size: 48))、自定义字体 .font(.custom(“Copperplate”, size: 48))。使用预定义字体可适配动态类型特性。
- Color(_:red:green:blue:) 提供色彩空间和 RGB 值来设置颜色。可以颜色名字从 Assets.xcassets 中加载颜色,Color(“colorName”)
- 使用 Assets.xcassets 颜色的好处,可以根据设备类型设置不同颜色,为亮暗设置不同颜色,可以用16进制定义
- .padding(.top, 16) .padding(.horizontal, 8) 等同 [.leading, .trailing] 都是8。.padding(.trailing, 24)
- 封装类的 modifier 的顺序重要,例如 padding,background
- .frame(width: 88, height: 88) 指定尺寸,frame(minWidth: 0, maxWidth: .infinity, alignment: .trailing) 指定最小最大宽,对其方式
- .clipShape(Circle()) 正方形内画圆,.clipShape(Capsule()) 胶囊形状
- Button.init(action:label:) label 接受一个闭包,是一个 ViewBuilder。或一个 title 一个 action
- 可以使用 CGFloat CGSize,可以遵从 View 协议自定义 View
- ForEach 列举元素,数组中元素需遵从 Identifiable 协议,或通过 ForEach(row, id: .self) 让元素支持 Hashable 也可以。
- VStack、HStack,VStack(spacing: 8) 指定间距,VStack(alignment: .trailing) 指定对齐方式
- if case 匹配的用法
- Spacer() 可伸缩空白
- .scaleEffect(scale) 做缩放
3 数据状态和绑定
- 限定小数格式,例如8位以内。
1 | var formatter: NumberFormatter = { |
- Double(result) 将字符串转为浮点数,可失败构造器
- 字符串String 有 contains(“.”) 方法,是否包含某字符串,返回Bool类型。遵从序列化协议 Sequence 的类型,有starts(with: “-“),是否以某个内容开头。字符串、数组都可以用
1 | let b = [1,2,3,4] |
- 可选值类型,可使用map,例如下例转浮点数为字符串,返回值也是可选类型
1 | let result: Double? = 3.14 |
- 纯函数:返回值只依赖入参,不改变其外部作用域的变量状态的函数
- @State 修饰,内部会被转换为一对 setter 和 getter,其赋值操作会引起界面刷新。
- @Binding 修饰,将值语义的属性 “转换” 为引用语义,传递属性时,使用$符号,称为投影属性(projection property)
- @State 和 @Binding 都是属性包装(Property Wrapper),属性包装可以简化代码。一段示例(77页)
- @State 适合 struct 或者 enum 这样的值类型,局限在body中使用,需要再view外部操作数据就不行。如果需要多个view共享和更改数据模型,使用ObservableObject。
- 遵从ObservableObject 协议,调用 objectWillChange.send() 或使用 @Published 修饰 都可以在属性发生改变时,去更新UI
- 数组 .joined() 合并为字符串。数组取片段的用法,下例。
1 | history = Array(total[..<index]) |
- reduce 用法,一种。
1 | brain = history.reduce(CalculatorBrain.left("0"), { result, item in |
- Slider 滑块用法,接受一个绑定值 Binding
1 | Slider(value: $model.slidingIndex, in: 0...Float(model.totalCount), step: 1) |
- 按钮 modal 行为展示视图
1 | Button("操作履历:\(model.history.count)") { |
- @EnvironmentObject 可以在view层级上避免不必要的属性传递,在初始化父视图的地方初始化数据,在深层子层级上可以直接使用。