颜值即正义,使用SwiftUI搭建版本更新弹窗

3,607 阅读4分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第19天,点击查看活动详情

在之前的章节中,完成了一个基本设置页面中的个人信息、账号绑定、通用设置的详情页。

在一章节,我们来完成简历管理的页面搭建。

那么这一章节,我们来完成版本更新的弹窗,用于手动获得更新。

本章相关项目

无人问津的设置页面,如何做到小而精美?

颜值即正义,使用SwiftUI搭建个人信息、账号绑定、通用设置详情页

颜值即正义,使用SwiftUI搭建简历管理详情页

效果预览

我们先来看看最终的效果图。示例:

1.png

逻辑梳理

我们来梳理了基本的交互逻辑,当我们在设置页面点击“版本更新”的时候,系统发送请求获得最新版本号,再由本地版本号进行对比,若是当前版本号低于请求回来的版本号信息,则打开系统更新弹窗,询问用户是否进行升级。

在版本更新弹窗中,提供“立即更新”和“关闭”2个按钮,点击“立即更新”,则跳转到AppStore进行更新;点击关闭,则关闭弹窗。

值得注意的是,当我们弹窗打开时,背景需要增加一个蒙层来突出弹窗信息,当关闭弹窗时,则蒙层对应消失。

逻辑梳理完成后,我们来完成样式部分的搭建。

页面蒙层

页面的蒙层我们可以看作一个白色的视图,只是它的透明度只有原来的一半。示例:

// MARK: 蒙层
struct MaskView: View {
    var bgColor: Color
    var body: some View {
        VStack {
            Spacer()
        }
        .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
        .background(bgColor)
        .edgesIgnoringSafeArea(.all)
        .opacity(0.5)
    }
}

蒙层是当我们点击“版本更新”按钮时才打开,因此我们需要声明一个变量进行切换显隐,示例:

@State private var showMaskView = false

我们将蒙层加到页面中,当我们showMaskView状态为true时,显示蒙层。示例:

// 打开蒙层
if showMaskView {
    MaskView(bgColor: .black)
}

点击触发的事件我们也加到原来的设置项中,示例:

Button(action: {
    self.showMaskView = true
}) {
    listItemView(itemImage: "icloud.and.arrow.down", itemName: "版本更新", itemContent: "Version 6.2.8")
}

2.gif

不错不错,点击“版本更新”打开蒙层的交互我们完成了。

版本更新弹窗

接下来,我们来绘制更新弹窗。根据图例,我们可以看到“版本更新”弹窗由一个Image图片,两段Text文字,一个“立即更新”按钮,一个“关闭”按钮组成,如下图所示:

3.png

我么先来绘制样式部分,我们创建一个新的视图CheckForUpdatesView,然后完成以下样式:

// MARK: 检查更新
struct CheckForUpdatesView: View {
    var body: some View {
        VStack(spacing: 32) {
            VStack(spacing: 10) {
                Image("update")
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .frame(width: 300)

                // 说明文字
                Text("软件更新提示Version6.2.9")
                    .font(.system(size: 17))
                    .foregroundColor(.black)
                Text("基础功能优化,抢先体验。")
                    .font(.system(size: 14))
                    .foregroundColor(.gray)

                Spacer()

                // 更新操作
                Button(action: {
                }) {
                    Text("立即更新")
                        .font(.system(size: 17))
                        .fontWeight(.bold)
                        .frame(minWidth: 0, maxWidth: .infinity)
                        .padding()
                        .foregroundColor(.white)
                        .background(Color(red: 88 / 255, green: 224 / 255, blue: 133 / 255))
                        .cornerRadius(30)
                        .padding(.horizontal, 20)
                }
            }
            .padding(.bottom, 40)
            .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: 350)
            .background(.white)
            .cornerRadius(8)
            .padding(.horizontal, 48)

            // 关闭按钮
            Image(systemName: "xmark.circle.fill")
                .font(.system(size: 32))
                .foregroundColor(.black)
                .opacity(0.5)
        }
    }
}

样式部分没啥好说的了,我们使用事先导入的图片作为展示的Image,然后使用VStack纵向排布两段文字。再绘制了2个按钮:一个文字按钮,一个图标按钮。

当我们点击关闭按钮时,需要关闭弹窗,这里我们需要绑定回原来在ContentView声明的变量,因此我们可以使用@Binding进行双向绑定,示例:

@Binding var showMaskView: Bool

然后在点击关闭按钮时,切换showMaskView状态,示例:

// 关闭按钮
Image(systemName: "xmark.circle.fill")
    .font(.system(size: 32))
    .foregroundColor(.black)
    .opacity(0.5)
    .onTapGesture {
        self.showMaskView = false
    }

就此,我们的弹窗部分就完成了。

最后我们把新视图CheckForUpdatesView加到主页面中,由于弹窗和蒙层一起出现,因此需要放在同一个判断逻辑里。示例:

// 打开蒙层
if showMaskView {
    MaskView(bgColor: .black)
    CheckForUpdatesView(showMaskView: $showMaskView)
}

完成后,我们来预览下最终效果。

项目预览

4.gif

恭喜你,完成了本章的全部内容!

快来动手试试吧。

如果本专栏对你有帮助,不妨点赞、评论、关注~