SwiftUI在19年时发布,不支持iOS13以下系统。根据苹果官方发布数据显示,目前全部iPhone中,只有8%的设备系统低于iOS 13,而最近4年的iPhone中,只有2%低于iOS13,所以现在是时候淘汰iOS 13以下系统,使用SwiftUI开发新项目了。

重点:

  • SwiftUI 的 view 是值,而非对象:它们是不可变的,用来暂时描述屏幕上应该显示什么。
  • 我们在一个 view 上几乎所有的方法调用 (像是 frame 或 background) 都会将 view 包装在一个修饰器中。因此,这些调用的顺序很重要,这一点和 UIView 里的属性不同。
  • 布局是自上而下的:父 view 向子 view 提供它们的可用空间,子 view 基于这个空间来决定自己的尺寸。
  • 我们不能直接更新屏幕上的内容。相反,我们必须修改状态属性 (比如 @State 或 @ObservedObject),然后让 SwiftUI 去找出 view 树的变化方式。

1.SwiftUI和UIKit的区别:

UIKit中创建的view或者view controller,都是长时间存在的UIView和UIViewController类的实例,然后我们修改它们的属性,来改变它们在屏幕上显示的内容。而SwiftUI中的view,是一个符合View协议的短时间存在的值,这些值描述了屏幕上应该显示的内容。这些值跟屏幕上看到的内容没有一对一的关系,view值只是暂时的,它可以随时被重新创建。

下图代码中,点击按钮,改变了counter的值以后,SwiftUI会重新计算这些view值,并更新屏幕显示内容

2.修饰器(modifier,ModifiedContent类型值)

SwiftUI 从最外层的 view 开始布局过程。ContentView 是 view 层级的根节点,布局系统会为它提供整个屏幕边界以进行布局。接下来,ContentView 把相同的尺寸提供给 VStack 让它自行布局。VStack 根据其子 view 的数量,将可用的竖直空间进行划分,并提供给每个view,如果view下面有修饰器,则会依据修饰器中包裹的条件文本标签来判断如何分配空间。

上图Button下方的.padding()就是一个修饰器,它的作用是将Text包装为一个ModifiedContent类型的值,这个值中包含有关应该如何设置 padding 填充的信息,如果在下面增加一个.background,又会把现有值包装起来创建一个新的ModifiedContent值,这一次将添加有关背景色的信息。

修饰器的顺序很重要,下面两张图,就是修饰器顺序不同出现的不同效果。第一张图实际运行时没有蓝框,这个框只是xcode标注给开发者看的,这个view的范围。

3.view更新

更改以@State、@ObservedObject 或者 @StateObject标记的属性的值,会触发view树的重新计算。

第一张截图中的counter的值被改变以后,SwiftUI 将再次访问 content view 的 body 属性,并取得对应新状态的 view 树。view树的类型在编译时就已经固定,无法改变,能改变的就是它的值,例如Text显示的文字,以及采用if语句的哪个分支。

更改状态属性是SwiftUI中唯一的更新view的方法,这种处理方式可以避免UIKit中view和app状态不同步这种常见错误。