摘要
这篇文章介绍了 SwiftUI 的基础使用方法。我主要通过观看 WWDC19 的视频学习 SwiftUI,我习惯在看教程的时候把重要的事项整理为笔记。如果你和我一样也是 iOS 的开发者,你一定会喜欢上 SwiftUI。和复杂的 UIViewController 说再见吧!
SwiftUI 不是为了重新发明轮子,它包含所有 UIKit 里原有的控件,手势控制等,还能更好地适配 iPhone,iPad,Mac,Apple TV 等平台。SwiftUI 的出现是为了让开发者更加集中精力在自己的定制功能,而不是基本的用户界面。
View 是用户界面的基础,每一个 View 定义了 App 里的一部分 UI。通过编写声明式 View 关系结构来完成对用户界面的定义。

Views and Modifiers - 视图和修饰
View 容器,以 VStack 为例,容器定义了内容里的层级关系。VStack 的定义是一个 struct,初始化函数包括了所有可以自定义的参数。例如 alignment,spacing。在 swiftUI 里通过 VStack(参数) 来初始化,例如:VStack(alignment: .leading)。

View Container Syntax - 视图容器语法
View 的 struct 定义中有变量前面标记为 @State 的情况,代表这个变量可以与传入的变量进行绑定。传入的变量需要在变量名前添加“$”,有点类似 C 代码里的传递指针。详细介绍在《Data Flow Through SwiftUI》课程。

Binding Syntax - 绑定语法
在一个已有的 View 后面添加 .Modifier(参数)。SwiftUI 里这种语法叫做 Modifier。它的功能是用自定义参数,从一个已有的 View 中创建新的 View。

Modifier - 修饰
SwiftUI 会按照 Modifier 的顺序把 Modifier 添加到视图架构中,所以 Modifier 添加的顺序会影响 View 最终的样式。SwiftUI 提倡开发者用模块化的 View,每个 View 有自己明确的视图样式和功能。

Modifier 的顺序会影响样式
通过编写类型为 View 的 struct 来实现自定义视图。
struct CustomView: View {
let var customVars: Type
var body: some View {
//视图内容
}
} struct 中的 var body: some View,定义了自定义视图中的内容。some 是 swift 的语法,表示自动推断返回类型。SwiftUI 鼓励多使用自定义视图,每一个自定义视图完成一些基础的功能和界面,最终把这些自定义视图组合起来完成一个功能强大,视图复杂的 App。

自定义视图
基于 UIKit 开发的自定义视图通常是定义一个 class,继承 UIView;SwiftUI 则是定义 View 类型的 struct。假如我们要修改视图的某些公共变量,例如 opacity 和 backgroundColor。在 UIKit 中,我们的自定义视图继承了 UIView 的所有公共属性;在 SwiftUI 中,我们通过给 View 添加 Modifier 来实现。这些 Modifier 灵活地遍布在各种 View 中,而不是像 UIKit 那样继承全部的 UIView 属性,从而达到轻量化,占用更小的存储空间的效果。
在 SwiftUI 中,View 被定义为一种 protocol。

View 被定义为一种 protocol
SwiftUI 提供了一系列原始视图,这些视图是视图的最小单位。例如:Text,Color,Image等等。开发者可以利用这些原始视图来构建复杂精细的用户界面。在《Building Custom Views in SwiftUI》课程有关于自定义视图的详细介绍。

Primitive Views 原始视图
SwiftUI 中的 View 是 struct,所以在生成 View 的时候是被定义为其输入的函数,即初始化函数。当输入发生变化时,SwiftUI 都会重新调用 View 的初始化函数,来获取视图的更新版本。
例如:代码中的 previousOrders 变量如果在运行中改变了,那么 SwiftUI 会根据改变的内容,自动使用改变后的变量来重新渲染视图。

View 的刷新方式
像 VStack 那样,Form 也是一种视图容器。Form 容器会根据平台特性(iOS,macOS)组合容器内容的排布方式。

Form 容器
按钮的内容可以自由组合,例如:开发者可以在 Button 里放一个 VStack,制作一个包含图片和文字描述的按钮。

Button 按钮
通过把自定义视图放进 NavigationView 容器中实现导航功能。可以通过子视图的 .navigationBarTitle(Text("Title")) 来设置 NavigationView 的标题。这个 Modifier 是一种“信息由子视图流向父视图”的例子,在子视图设置 navigationBarTitle 会反馈到父视图的 NavigationView 中。可使用 NavigationButton(destination)来从一个页面导航到另一个页面。

在 App 中完成页面导航