持续创造,加快成长!这是我参加「日新方案 6 月更文应战」的第11天,点击查看活动详情。
在本章中,你将学会运用Transition
过渡Animation
动画构建一个AppStore
运用商场引荐页面。
项目布景
在AppStore
运用商场中,咱们能够看到一个Apple
常用的交互形式,它选用线性动画,当用户点击引荐的卡片视图时,卡片会慢慢弹出,然后进入到对应的详情页中。
这种动画交互很有意思。
那么本章,咱们就尝试构建一个AppStore
运用商场引荐页面。
首先,创立一个新项目,命名为SwiftUITransition
。

素材预备
咱们先导入一批图片作为卡片视图展现的封面。

Model预备
然后,咱们构建下Model
。新建一个swift
类型的文件,命名为Model.swift
。
咱们分析下卡片视图所涵盖的内容:封面图片、类目、标题、副标题、内容,咱们在Model
中创立对应的参数,并且创立一些示例数据。
import SwiftUI
struct Model: Identifiable {
var id = UUID()
var category: String
var headline: String
var subHeadline: String
var content: String
var image: UIImage
}
#if DEBUG
var sampleModels = [
Model(category: "引荐", headline: "修改精选", subHeadline: "本周引荐语录", content: "要想在一个生活圈中生活下去,或许融入职场的气氛,首先你要学习这个圈子的文明和发展史,并尝试用这个圈子里面的“话术”和他们交流,这样才能顺畅地融入这个圈子。", image: UIImage(named: "image01")!),
Model(category: "热榜", headline: "每日热榜", subHeadline: "今天抢手事情推送", content: "关于产品经理来说,用户真实运用产品或产品上线交付后,产品的价值才真实发挥出来。这时候,价值的多少就取决于产品自身所供给的服务,以及产品的设计者后续的运营了。", image: UIImage(named: "image02")!),
Model(category: "头条", headline: "精选头条", subHeadline: "你重视的才是头条", content: "在任何环境中都需求去发现他人身上的长处,但在学习他人长处的一起,也不要忘了自己自身的个人特性,因为这才是你的长处。遇到困难时,咱们要迎难而上,而不是畏畏缩缩。找到一个清晰的目标,不在乎他人的眼光,努力去做就好了。", image: UIImage(named: "image03")!),
]
#endif

咱们界说了一个Model
结构体,它遵循Identifiable
协议,这样咱们就能够运用id
定位到结构体中的实例。
咱们运用var
声明晰卡片视图需求用到的变量,并声明晰其类型特点:String
、UIImage
等。并创立了一个sampleModels
数组,创立了一个示例数据作为View
视图中展现的内容。
以上便是咱们Model
承载的内容,在MVVM
、MVC
开发模式中,根本运用的都是这样的办法。
摘要视图
在AppStore
运用商场引荐页面,咱们能够看到能够向下翻滚一个个卡片视图。一张张卡片上展现着部分引荐信息,包括文章的图片、类别、标题和副标题。
咱们能够创立一个新的结构体用来展现卡片视图。
//摘要视图
struct SummaryView: View {
let category: String
let headline: String
let subHeadline: String
@Binding **var** isShowContent: Bool
var body: some View {
VStack(alignment: .leading) {
Spacer()
Rectangle()
.frame(minHeight: 100, maxHeight: 150)
.overlay(
HStack {
VStack(alignment: .leading) {
Text(self.category.uppercased())
.font(.subheadline)
.fontWeight(.bold)
.foregroundColor(.secondary)
Text(self.headline)
.font(.title)
.fontWeight(.bold)
.foregroundColor(.primary)
.minimumScaleFactor(0.1)
.lineLimit(2)
.padding(.bottom, 5)
if !self.isShowContent {
Text(self.subHeadline)
.font(.subheadline)
.foregroundColor(.secondary)
.minimumScaleFactor(0.1)
.lineLimit(3)
}
}
.padding()
Spacer()
}
)
}
.foregroundColor(.white)
}
}
上述代码中,咱们构建了一个SummaryView
结构体,用来构建卡片视图内容的摘要内容。
咱们运用let
声明晰类别category
、标题headline
和副标题subHeadline
三个常量及其类型,在结构体主体内容上,咱们创立了一个Rectangle
视图,并将和标题和副标题进行overlay
叠加。
叠加部分,咱们运用横向视图,包裹了三个Text
文本,Text
文本来源于咱们声明的常量,为之后在主视图赋值运用。
这儿科普一个知识点。
minimumScaleFactor
修饰符,运用后,Text
文本内容能够依据展现的空间巨细主动缩小文本的字体巨细。因为考虑到headline
标题和副标题subHeadline
可能会很长的关系,咱们这儿设定了能够缩小到原始巨细的10%
。
完结后,咱们在ContentView
视图中展现下内容。
SummaryView(category: sampleModels[0].category, headline: sampleModels[0].headline, subHeadline: sampleModels[0].subHeadline, isShowContent: .constant(false))
咱们在ContentView
视图实例化了一个SummaryView
视图,数据来源咱们运用下标的办法拜访sampleModels
数组中的数据,这儿取的的是[0]
第一条,关于是否展现内容isShowContent
咱们暂时运用false
。
咱们预览下作用:

完好视图
完结了摘要视图后,咱们来尝试完结完好的视图展现。
struct CardView: View {
let category: String
let headline: String
let subHeadline: String
let image: UIImage
var content: String = ""
@Binding var isShowContent: Bool
var body: some View {
ScrollView {
VStack(alignment: .leading) {
Image(uiImage: self.image)
.resizable()
.scaledToFill()
.frame(height: min(self.image.size.height / 3, 500))
.border(Color(.sRGB, red: 150 / 255, green: 150 / 255, blue: 150 / 255, opacity: 0.1), width: self.isShowContent ? 0 : 1)
.cornerRadius(15)
.overlay(
SummaryView(category: self.category, headline: self.headline, subHeadline: self.subHeadline, isShowContent: self.$isShowContent)
.cornerRadius(self.isShowContent ? 0 : 15)
)
if self.isShowContent {
Text(self.content)
.foregroundColor(Color(.darkGray))
.font(.system(.body, design: .rounded))
.padding(.horizontal)
.padding(.bottom, 50)
.transition(.move(edge: .top))
.animation(.linear, value: 0)
}
}
}
.shadow(color: Color(.sRGB, red: 64 / 255, green: 64 / 255, blue: 64 / 255, opacity: 0.3), radius: self.isShowContent ? 0 : 15)
}
}
上述代码中,咱们界说了一个CardView
结构体,声明晰需求用到的参数:category
类目、headline
主标题、subHeadline
副标题、image
主要展现图片、content
详情内容、以及是否展现内容isShowContent
。
咱们在ContentView
视图实例化CardView
视图,和之前摘要视图的办法一致,拜访sampleModels
数据数据。
CardView(category: sampleModels[0].category, headline: sampleModels[0].headline, subHeadline: sampleModels[0].subHeadline, image: sampleModels[0].image,content: sampleModels[0].content, isShowContent: .constant(false))
咱们预览下作用:

咱们再把isShowContent
是否展现详情改为true
,再预览下作用。

祝贺你,完结了根底页面的制作!
因为章节内容过多,咱们将分章节进行学习。
快来着手试试吧!
如果本专栏对你有帮助,不妨点赞、评论、重视~