Section 14 : Data and Image Literal - HH-Ge/BuildAnAppWithSwiftUI GitHub Wiki
- 数据和图像字面量(13'30")
Work with arrays and data models to create a loop of components in SwiftUI.
在 SwiftUI 中使用数组和数据模型创建系列组件。
1. 建立数据模型
上一节的课程卡片只是简单的重复,内容都是一样的。现在如果要展示不一样的内容,可以把他们一致的属性组合成数据模型,其实就是抽象的意思。在SectionView.swift 中的最后声明一个结构体,用来描述抽象出来的数据模型。
struct Section: Identifiable {
var id = UUID() // 编号,唯一的
var title: String // 标题
var text: String // 课时
var logoName: String // Logo名
var image: Image // 图片
var color: Color // 颜色
}
然后再创建一个全局变量用来保存数据并提供给视图使用。为了保存多个课程,将数据类型设为由课程组成的数组。这里暂时先写一个课程。
let sectionData = [
Section(title: "SwiftUI \n原型设计", text: "共 18 讲", logoName: "Logo1", image: Image("Card1"), color: Color("card1"))
]
2. 在视图用引用数据
(1)修改 SectionView
在视图的 body 前声明一个提供数据的变量 section,声明其类型为 Section。然后将视图中各个组件对应显示的内容改为数据表示。
struct SectionView: View {
var section: Section // 声明类型为 Section 的变量用来传递数据
var body: some View {
VStack {
HStack(alignment: .top) {
Text(section.title) // 使用变量替代原先的静态值
.font(.system(size: 24, weight: .bold))
.frame(width: 160, alignment: .leading)
.foregroundColor(.white)
Spacer()
Image(section.logoName) // 使用变量替代原先的静态值
}
Text(section.text) // 使用变量替代原先的静态值
.frame(maxWidth: .infinity, alignment: .leading)
section.image // 使用变量替代原先的静态值
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 210)
}
.padding(.top, 20)
.padding(.horizontal, 20)
.frame(width: 275, height: 275)
.background(section.color) // 使用变量替代原先的静态值
.cornerRadius(30)
.shadow(color: section.color.opacity(0.3), radius: 20, x: 0, y: 20) // 使用变量替代原先的静态值
}
}
(2)修改 HomeView
由于 sectionData 是全局的,所以不需要在视图的 body 前再次声明就可以直接在循环中使用。
ForEach(sectionData) { item in // 使用变量替代原先的静态值,遍历数组
SectionView(section: item) // 子视图
}
(3)添加几个数据
在 sectionData 中,添加几条数据,数据直接用逗号隔开
let sectionData = [
Section(title: "SwiftUI \n原型设计", text: "共 18 讲", logoName: "Logo1", image: Image("Card1"), color: Color("card1")),
Section(title: "SwiftUI \nApp开发", text: "共 20 讲", logoName: "Logo2", image: Image(uiImage:#imageLiteral(resourceName: "wowLM")), color: Color(#colorLiteral(red: 0.3411764801, green: 0.6235294342, blue: 0.1686274558, alpha: 1))),
Section(title: "SwiftUI \nMac开发", text: "共 15 讲", logoName: "Logo3", image: Image("Card3"), color: Color("card3"))
]
这样在预览中可以看见有三张卡片了。卡片中的内容就数据提供的。
3. 图像字面量(image literal)
与颜色字面量一样,图像也可以使用字面量。与颜色不同的是,颜色是直接在 Color()
的参数中输入 color literal
,图像则需要先输入参数名 uiImage
和冒号:
后再输入image literal
。然后双击小图标就可以选择 assets 目录下的图像了。
小窍门
在全局变量 sectionData 的声明中,也可以使用字面量。只是没有自动完成的提示。我们可以找个空白行,输入想要的字面量 colorliteral 或者 imageliteral(应该输入到一半多就能有提示出现了),确定后,将色块或者小图标剪切粘贴到变量的声明中,这样下次我们双击色块就可以直接使用字面量了。
本节小结
- 将具有相同属性的数据抽象成结构体,在视图中声明类型为这个结构体的变量,使用变量的属性将值传递给组件。
- 数组,方括号括起来的由逗号分隔的一系列同样类型的元素。
- foreach 用来遍历数组,每次变量会取出当前元素。
- 图像也可以使用字面量,和颜色字面量不同,需要加上参数名 UIImage:
- 字面量和预览让原型设计变得非常方便。
接下来
视图滚动时的 3D 动画