承接上一章内容,我们继续完成构建一个AppStore
应用市场推荐页面。
样式修订
由于我们使用frame
修饰符限制了CardView
视图的高度,而没有设定展示的宽度,那么就有可能会存在当我们image
图片太大时,整个ContentView
视图被撑开的情况。
.frame(height: min(self.image.size.height / 3, 500))
为避免这种情况,我们需要设定整个CardView
视图的宽度,避免超出展示的边缘。
在之前的章节中,我们介绍过GeometryReader
容器的使用方法,它可以访问父视图的宽度,得到屏幕的宽度,我们就可以通过屏幕宽度设置CardView
视图展示的宽度。
GeometryReader { geometry in //代码块 }
然后,我们就可以直接设置image
图片展示的宽度为GeometryReader
容器的宽度。
.frame(width: geometry.size.width, height: min(self.image.size.height/3, 500))
关闭按钮
完成了部分样式调整后,我们来完成下点击摘要视图展示完整视图,然后完整视图要想切换到摘要视图的样式部分,我们发现还需要一个关闭按钮。
在完整视图中,我们在其右上角用ZStack
层叠一个colseButton
关闭按钮。
// 关闭按钮 if self.isShowContent { HStack { Spacer() Button(action: { self.isShowContent = false }) { Image(systemName: "xmark.circle.fill") .font(.system(size: 26)) .foregroundColor(.white) .opacity(0.7) } } .padding(.top, 50) .padding(.trailing) }
完成后,我们回到ContentView
视图。
之前,我们使用下标的方法展示了一个卡片视图方便我们编程演示需要,现在我们完成了基本页面样式,我们重新来修改下ContentView
视图展示内容。
和之前的章节一样,我们使用ForEach
循环的方式遍历数据。
struct ContentView: View { var body: some View { ScrollView { ForEach(sampleModels.indices,id: \.self) { index in GeometryReader {inner in CardView(category: sampleModels[index].category, headline: sampleModels[index].headline, subHeadline: sampleModels[index].subHeadline, image: sampleModels[index].image, content: sampleModels[index].content , isShowContent: .constant(false)) .padding(.horizontal, 20) } .frame(height: min(sampleModels[index].image.size.height / 3, 500)) } } } }
上述代码中,我们构建了一个ScrollView
滚动视图,便于展示多张卡片视图。然后我们使用ForEach
循环遍历sampleModels
数组中的数据,在CardView
卡片视图中,我们使用[index]
下标定位的方式获得sampleModels
数组中的数据,最后我们使用frame
修饰符调整卡片视图的大小。
看起来不错。
顶部导航栏
下面我们在主体基础上完成了顶部导航栏的内容。顶部导航栏由当前日期、“今天”文字、还有用户头像组成,我们可以定义一个结构体TopBarView
来完成样式部分的内容。
struct TopBarView: View { var body: some View { HStack(alignment: .lastTextBaseline) { VStack(alignment: .leading) { Text("6月5日 星期天") .font(.caption) .foregroundColor(.secondary) Text("今天") .font(.largeTitle) .fontWeight(.heavy) } Spacer() Image("image01") .resizable() .frame(width: 40, height: 40) .clipShape(Circle()) .overlay(Circle().stroke(Color.gray, lineWidth: 1)) } } }
然后我们在ContentView视图中展示TopBarView的内容。
好像还不错,但这里我们是使用Text文本的形式展示当前的日期的,这不够优雅,我们需要每次打开的时候都获取当前的系统时间,我们可以使用下面的方法。
func getCurrentDate(with format: String = "EEEE, MMM d") -> String { let dateFormatter = DateFormatter() dateFormatter.dateFormat = format return dateFormatter.string(from: Date()) }
然后,我们只需要在Text
文本中调用这个方法,就可以展示系统当前日期了。
小结
AppStore应用市场推荐页面的样式部分我们就完成了,在第一章我们完成了基础页面的绘制,包括摘要内容展示视图和完整内容展示视图。
在本章中,我们修订了部分的样式,在完整展示视图上增加了关闭按钮,最后还增加了顶部导航栏。
那么下一章,我们将学习如何从摘要视图卡片,点击打开完整视图内容的交互动作,这也是整个项目中最难的部分。
快来动手试试吧!