SwiftUI极简教程37:构建一个AppStore应用市场推荐页面(下)

简介: 承接上一章的内容,我们继续完成构建一个AppStore应用市场推荐页面。本章我们完成最难的部分,即摘要视图和完整视图的页面状态切换。

ContentView中,我们使用.constanttruefalse来完成切换,如果我们要实现点击不同卡片视图都进行切换,那么我们需要声明一个变量数组来记录每一个卡片视图的切换状态。

@State private var showContents: [Bool] = Array(repeating: false, count: sampleModels.count)

我们声明了一个开放的变量showContents数组,它存储每一个sampleModels数组中的状态变量,因为我们默认是展示摘要视图,所以这里都用false

由于我们的ContentView结构体中需要展示摘要视图,又要展示完整的内容视图。因此我们需要知道当前处于什么模式,我们这里使用计算属性来计算视图的当前模式。

enum ContentMode {
    case list
    case content
}
private var contentMode: ContentMode {
    self.showContents.contains(true) ? .content : .list
}

上述代码中,我们定义了一个ContentMode枚举,它有两种状态:list摘要列表视图、content完整内容视图。

然后我们声明了一个开放变量contentMode,遵循ContentMode协议,它根据我们之前声明的showContents变量,判断是处于摘要列表模式,还是完整内容模式。

我们要将声明好的变量绑定到CardView卡片视图中,并且我们再需要为CardView卡片视图添加一个点击事件,用于切换状态。

image.png

运行预览下,我们可以看到我们完成了点击卡片,卡片从摘要视图切换到完整视图了。

但我们发现了一些问题,首先是从摘要视图切换到完整内容视图时,完整内容视图它没有铺满全屏,然后是切换到完整视图时,内容的部分看不到了。

我们一点点来完善它。

首先是摘要视图切换到完整视图时,应该铺满全屏。

.padding(.horizontal, self.showContents[index] ? 0 : 20)
.opacity(self.contentMode == .list || self.contentMode == .content && self.showContents[index] ? 1 : 0)

我们设置边距padding,它根据showContents的状态进行切换,如果是完整内容视图情况下,我们的padding0

我们还增加了一个opacity修饰符,用来展示我们选中的卡片浮在最上层,所以我们隐藏非选中的卡片内容。

image.png

不错的样子。

我们完整内容模式下还需要隐藏顶部导航栏,我们也需要给顶部导航栏添加判断条件,根据当前模式contentMode判断是否隐藏。

.opacity(self.contentMode == .content ? 0 : 1)

image.png

额?上面还留有一段空白?

这是因为我们设置了GeometryReader几何容器,而且我们之前还定义了整个卡片视图的高度不得超过500,那我们这里如果要调整卡片视图的位置,我们就需要再加一个GeometryReader几何容器包裹住整个滚动视图。

然后再重新根据屏幕高度设置卡片视图的显示区域。

.frame(height: self.showContents[index] ? fullView.size.height + fullView.safeAreaInsets.top + fullView.safeAreaInsets.bottom : min(sampleModels[index].image.size.height/3, 500))

image.png

上述代码中,我们在最外层的GeometryReader几何容器中使用了参数fullView,它允许我们访问屏幕的大小,因为最外层的GeometryReader几何容器是获得屏幕的大小。

然后我们调整卡片视图的尺寸为展示的区域加上顶部和底部的安全区域,这样我们就获得了全屏展示的效果。

额?全屏时全屏了,可上面还是有空白的区域?

image.png

这是因为卡片视图确实会延长其高度,但不会改变它位置,所以就不会覆盖到上面的屏幕。

那么我们如何将整个视图移动上去呢?

移动,是个好办法。

我们在内层的GeometryReader几何容器中增加一个offset修饰符,用来移动位置,移动多少位置好呢?移动到整个内层的GeometryReader几何容器的Y轴为0就行了。

.offset(y: self.showContents[index] ? -inner.frame(in: .global).minY : 0)

image.png

不错!恭喜你,完成了本章节的所有内容。

image.png

本章代码

struct ContentView: View {
    @State private var showContents: [Bool] = Array(repeating: false, count: sampleModels.count)
    enum ContentMode {
        case list
        case content
    }
    private var contentMode: ContentMode {
        showContents.contains(true) ? .content : .list
    }
    var body: some View {
        GeometryReader { fullView in
            ScrollView {
                VStack(spacing: 40) {
                    TopBarView()
                        .padding(.horizontal, 20)
                        .opacity(self.contentMode == .content ? 0 : 1)
                    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: self.$showContents[index])
                                .offset(y: self.showContents[index] ? -inner.frame(in: .global).minY : 0)
                                .padding(.horizontal, self.showContents[index] ? 0 : 20)
                                .opacity(
                                    self.contentMode == .list || self.contentMode == .content && self.showContents[index] ? 1 : 0)
                                .onTapGesture {
                                    self.showContents[index] = true
                                }
                        }
                        .frame(height: self.showContents[index] ? fullView.size.height + fullView.safeAreaInsets.top + fullView.safeAreaInsets.bottom : min(sampleModels[index].image.size.height / 3, 500))
                    }
                }
            }
        }
    }
}

快来动手试试吧!

相关文章
|
6月前
|
开发者 iOS开发
【教程】苹果推送证书的创建和使用流程详解
【教程】苹果推送证书的创建和使用流程详解
|
存储
发布&选择发布,使用SwiftUI搭建一个新建发布弹窗(上)
发布&选择发布,使用SwiftUI搭建一个新建发布弹窗(上)
93 0
|
存储
发布&选择发布,使用SwiftUI搭建一个新建发布弹窗(下)
发布&选择发布,使用SwiftUI搭建一个新建发布弹窗(下)
212 0
|
存储 数据安全/隐私保护 Android开发
苹果IOS应用上架AppStore的流程与教程
苹果IOS应用上架AppStore的流程与教程
|
存储 安全 Linux
Hbuilder 用自有证书打包 ios App 上架 AppStore 流程
最近在用 Hbuilder 做跨平台开发,经过一番研究终于在苹果商店上架成功了一款产品!这款产品就很简单,直接用 hbuilder 打包好,然后上传到商店即可。
Hbuilder 用自有证书打包 ios App 上架 AppStore 流程
|
安全 Linux 网络安全
最简单易懂的ios p12证书 和描述文件的创建,IPA上传,最完整的ios上架苹果商店教程
创建AppID创建AppID在windows系统下创建 app 打包ios需要的证书和描述文件,和ios上架苹果商店流程
最简单易懂的ios p12证书 和描述文件的创建,IPA上传,最完整的ios上架苹果商店教程
|
存储 监控 安全
2022苹果AppStore应用商店上传与APP上传流程必看(基础篇)​
2022苹果AppStore应用商店上传与APP上传流程必看(基础篇)​
|
存储 安全 JavaScript
app提交上架最新流程 ios
app提交上架最新流程 ios
|
安全 Linux 网络安全
【描述文件-上架】IPA上传小助手一键制作IOS上架appstore描述文件 iOS Distribution环境苹果描述文件制作教程​
苹果上架证书基础项目需要包括 A).IOS生产环境证书,即iOS Distribution环境证书; B).APPID包名制作,即Bundle id的制作; C).APP的描述文件,即APP证书与iOS Distribution 和 Bundle id 一一对应的描述文件;
|
存储 监控 安全
2022苹果AppStore应用商店上传与APP上传流程必看(基础篇)
如果App想要成功出现在商店中,开发者还需要经过上传操作和苹果公司的严格审核。同时,在App上架App Store时,如有违规,将受到苹果公司的处罚。此外,优质app也会得到苹果的推荐,通过优质曝光和苹果官方背书获得更多用户增长。
下一篇
无影云桌面