Section 14 : Data and Image Literal

Section 14 : Data and Image Literal - 数据和图像字面量(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(应该输入到一半多就能有提示出现了),确定后,将色块或者小图标剪切粘贴到变量的声明中,这样下次我们双击色块就可以直接使用字面量了。

本节小结

本节代码请参见 GitHub码云

  • 将具有相同属性的数据抽象成结构体,在视图中声明类型为这个结构体的变量,使用变量的属性将值传递给组件。
  • 数组,方括号括起来的由逗号分隔的一系列同样类型的元素。
  • foreach 用来遍历数组,每次变量会取出当前元素。
  • 图像也可以使用字面量,和颜色字面量不同,需要加上参数名 UIImage:
  • 字面量和预览让原型设计变得非常方便。

接下来

视图滚动时的 3D 动画

发布了51 篇原创文章 · 获赞 15 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/hh680821/article/details/105074476