SwiftUI极简教程06:代码优雅复用

简介: SwiftUI极简教程06:代码优雅复用

在本章中,你将学会如何处理可以复用的代码块。

在定价方案视图中,可以看到3个定价方案的样式还有代码是极其相似的。

image.png


和设计的逻辑一样,代码的逻辑也是是“复制”第一个定价方案的视图的代码,然后再修改颜色、字体、或者加多一些文字。

但他们的主体结构是一样的。

那么我们是不是可以只需要写一次代码,然后把文字什么的再复用重定义。

这样可以大大减少代码量,且代码阅读起来更加清晰,做到“优雅写代码”的目的。


//定价方案子视图
struct pricingView: View {
    var body: some View {
        HStack {
            // 连续包月
            ZStack {
                VStack {
                    Text("连续包月")
                        .fontWeight(.bold)
                        .font(.system(size: 17))
                        .foregroundColor(Color(red: 190 / 255, green: 188 / 255, blue: 184 / 255))
                    Text("¥18")
                        .fontWeight(.bold)
                        .font(.system(size: 30))
                        .foregroundColor(Color(red: 239 / 255, green: 129 / 255, blue: 112 / 255))
                }
                .frame(minWidth: 0, maxWidth: .infinity, minHeight: 90)
                .padding(20)
                .background(Color("faf7f3"))
                .overlay(RoundedRectangle(cornerRadius: 6)
                            .stroke(Color(red: 202 / 255, green: 169 / 255, blue: 106 / 255), lineWidth: 2))
                // 首月特惠
                Text("首月特惠")
                    .font(.system(size: 14))
                    .fontWeight(.bold)
                    .foregroundColor(.white)
                    .padding(5)
                    .background(Color(red: 202 / 255, green: 169 / 255, blue: 106 / 255))
                    .cornerRadius(4)
                    .offset(x: 0, y: -65)
            }
            // 1个月
            VStack {
                Text("1个月")
                    .fontWeight(.bold)
                    .font(.system(size: 17))
                    .foregroundColor(Color(red: 190 / 255, green: 188 / 255, blue: 184 / 255))
                Text("¥30")
                    .fontWeight(.bold)
                    .font(.system(size: 30))
                    .foregroundColor(Color(red: 239 / 255, green: 129 / 255, blue: 112 / 255))
            }
            .frame(minWidth: 0, maxWidth: .infinity, minHeight: 90)
            .padding(20)
            .background(Color(red: 244 / 255, green: 244 / 255, blue: 245 / 255))
            .cornerRadius(10)
            // 12个月
            VStack {
                Text("12个月")
                    .fontWeight(.bold)
                    .font(.system(size: 17))
                    .foregroundColor(Color(red: 190 / 255, green: 188 / 255, blue: 184 / 255)
                Text("¥228")
                    .fontWeight(.bold)
                    .font(.system(size: 30))
                    .foregroundColor(Color(red: 239 / 255, green: 129 / 255, blue: 112 / 255))
                Text("¥19.00/月")
                    .fontWeight(.bold)
                    .font(.system(size: 17))
                    .foregroundColor(Color(red: 190 / 255, green: 188 / 255, blue: 184 / 255))
            }
            .frame(minWidth: 0, maxWidth: .infinity, minHeight: 90)
            .padding(20)
            .background(Color(red: 244 / 255, green: 244 / 255, blue: 245 / 255))
            .cornerRadius(10)
        } // HStack结束位置
        .padding(.horizontal)
    }
}
复制代码


说干就干!

首先分析下代码的相同点。

Text()下,设置字重、字体、字体颜色,在整个VStack包裹下,设置尺寸、边距、背景颜色、边框圆角。

我们发现,除了定价方案的标题不同(连续包月、1个月、12个月)、不同定价方案的价格不同(¥18、¥30、¥228)、背景颜色不同,其他都一样。

既然这些都可以复用,那么我们可以将可以复用的参数脱离出来。

先定义一个变量,再在代码中设定不同的变量值,就可以达到全部复用的效果。

先定一个标准的定价方案,定义了一个title变量,它是字符串类型,定义了一个价格变量,也是字符串类型,定一个一个背景颜色,它是颜色类型。

然后将定义的变量换到下面的代码中。


//定价方案
struct pricingView: View {
//定义变量
var title: String
var price: String
var bgColor: Color
var body: some View {
    VStack {
        Text(title)    //定义的titie
            .fontWeight(.bold)
            .font(.system(size: 17))
            .foregroundColor(Color(red: 190 / 255, green: 188 / 255, blue: 184 / 255))
        Text(price)    //定义的price
            .fontWeight(.bold)
            .font(.system(size: 30))
            .foregroundColor(Color(red: 239 / 255, green: 129 / 255, blue: 112 / 255))
        }
        .frame(minWidth: 0, maxWidth: .infinity, minHeight: 90)
        .padding(20)
        .background(bgColor)    //定义的背景颜色
    }
复制代码


定义完变量后,我们可以看到系统报错了,不用担心。

这因为我们pricingView子视图中定义了3个变量,但在主视图引用的时候,主视图不知道这3个变量是什么值,只知道它的类型。

所以系统提醒我们需要加上具体的值。

我们可以点击“Fix”,Xcode会自动帮我们加上缺少的值。


image.png

“Fix”后,Xcode将缺少的变量补充了进来。

这时候,我们需要给变量赋予真实的值。

示例:title赋予"连续包月”,price赋予"¥18”,bgColor赋予Color("faf7f3”)。

image.png

// 定价方案
pricingView(title: "连续包月", price: "¥18", bgColor: Color("faf7f3"))

image.png


很好,我们已经创建好了1个定价方案了!

像UI稿一样,我们需要3个定价方案,由于我们已经拆离开可以复用的代码了,那么我们只需要在主视图复制就行了,而无需再额外复制一大段代码。


// 定价方案
    //连续包月
    pricingView(title: "连续包月", price: "¥18", bgColor: Color("faf7f3"))
    //1个月
    pricingView(title: "1个月", price: "¥30", bgColor: Color(red: 244 / 255, green: 244 / 255, blue: 245 / 255))
    //12个月
    pricingView(title: "12个月", price: "¥228", bgColor: Color(red: 244 / 255, green: 2


image.png

由于在主视图中,我们的标题和定价方案是放在一个VStack里面的,而3个定价方案需要横向分布,也就是使用HStack。

那我们只需要在主视图中将3个定价方案放在一个HStack中,这样它们就能横向排列了。

// 定价方案
HStack {
    //连续包月
    pricingView(title: "连续包月", price: "¥18", bgColor: Color("faf7f3"))
    //1个月
    pricingView(title: "1个月", price: "¥30", bgColor: Color(red: 244 / 255, green: 244 / 255, blue: 245 / 255))
    //12个月
    pricingView(title: "12个月", price: "¥228", bgColor: Color(red: 244 / 255, green: 244 / 255, blue: 245 / 255))
}


image.png

下一步,我们修订下样式,我们可以看到第一个定价方案是有圆角边框的,其他两个定价方案是有圆角的。

那么我们需要单独为第一个定价方案加圆角边框,其他两个定价方案加圆角。

image.png

// 定价方案
HStack {
    //连续包月
    pricingView(title: "连续包月", price: "¥18", bgColor: Color("faf7f3”))
        .overlay(RoundedRectangle(cornerRadius: 6).stroke(Color(red: 202 / 255, green: 169 / 255, blue: 106 / 255), lineWidth: 2))
    //1个月
    pricingView(title: "1个月", price: "¥30", bgColor: Color(red: 244 / 255, green: 244 / 255, blue: 245 / 255))
        .cornerRadius(10)
    //12个月
    pricingView(title: "12个月", price: "¥228", bgColor: Color(red: 244 / 255, green: 244 / 255, blue: 245 / 255))
        .cornerRadius(10)
}

image.png

下一步,我们看到UI稿中,第一个定价有【首月特惠】的标识,其他两个定价方案是没有的。

那么我们需要再给第一个定价方案用ZStack包裹,然后再里面添加一个【首月特惠】的标识。

image.png

//连续包月
ZStack {
    // 连续包月
    pricingView(title: "连续包月", price: "¥18", bgColor: Color("faf7f3"))
        .overlay(RoundedRectangle(cornerRadius: 6).stroke(Color(red: 202 / 255, green: 169 / 255, blue: 106 / 255), lineWidth: 2))
    // 首月特惠
    Text("首月特惠")
        .font(.system(size: 14))
        .fontWeight(.bold)
        .foregroundColor(.white)
        .padding(5)
        .background(Color(red: 202 / 255, green: 169 / 255, blue: 106 / 255))
        .cornerRadius(4)
        .offset(x: 0, y: -65)
    }

image.png

这时候,我们会发现样式基本okay了。

但有个问题,主视图的代码好像太多了,不够优雅。

结合上一章所学的代码分组管理,我们可以把【首月特惠】单独抽离出来成为一个子视图。

鼠标移动到ZStack定价方案里的Text()视图,按住command键,点击选择Text()视图,选择Extract SubView。


image.png

image.png


在得到新的子视图后,我们依旧需要重命名。

我们把首月特惠的ExtractedView更名为specialOfferView。

鼠标定位到原来没有命名的ExtractedView位置,点击鼠标右键,选择Refactor,选择Rename。

image.png

image.png

很好!代码优雅多了!

image.png

然后,我们再给HStack加个.padding。

image.png

你以为完成了吗?并不!

我们看到第三个定价方案还有1个Text(“¥19.00/月”),而其他定价方案没有。

image.png

先思考下怎么做。

在pricingView里加一个Text()?先试试吧。

和之前一样,我们定一个perPrice变量,它是String类型。

然后在pricingView中加上Text(perPrice)的代码。


//定价方案子视图
struct pricingView: View {
    // 定义变量
    var title: String
    var price: String
    var perPrice: String
    var bgColor: Color
    var body: some View {
        VStack {
            Text(title)
                .fontWeight(.bold)
                .font(.system(size: 17))
                .foregroundColor(Color(red: 190 / 255, green: 188 / 255, blue: 184 / 255))
            Text(price)
                .fontWeight(.bold)
                .font(.system(size: 30))
                .foregroundColor(Color(red: 239 / 255, green: 129 / 255, blue: 112 / 255))
            Text(perPrice)
                .fontWeight(.bold)
                .font(.system(size: 17))
                .foregroundColor(Color(red: 190 / 255, green: 188 / 255, blue: 184 / 255))
        }
        .frame(minWidth: 0, maxWidth: .infinity, minHeight: 90)
        .padding(20)
        .background(bgColor)
    }
}


image.png


再回到主视图中,补充缺失的变量。

点击“Fix”,Xcode会自动补充缺失的变量。

image.png

补充缺失的变量后,根据定义好的数据类型,完成相对应的数据即可。

image.png

这样,我们就完成了整个定价方案的编程!


// 定价方案
HStack {
    // 连续包月
    ZStack {
        pricingView(title: "连续包月", price: "¥18", perPrice: "", bgColor: Color("faf7f3")
            .overlay(RoundedRectangle(cornerRadius: 6).stroke(Color(red: 202 / 255, green: 169 / 255, blue: 106 / 255), lineWidth: 2))
        // 首月特惠
        specialOfferView()
    }
    // 1个月
    pricingView(title: "1个月", price: "¥30", perPrice: "", bgColor: Color(red: 244 / 255, green: 244 / 255, blue: 245 / 255))
        .cornerRadius(10)
    // 12个月
    pricingView(title: "12个月", price: "¥228", perPrice: "¥19.00/月", bgColor: Color(red: 244 / 255, green: 244 / 255, blue: 245 / 255))
        .cornerRadius(10)
    }
    .padding()


image.png


相关文章
|
9月前
|
存储 vr&ar
大师学SwiftUI第6章 - 声明式用户界面 Part 1
在上一章,我们介绍了SwiftUI的主要特性,声明式语法。借助SwiftUI,我们可以按希望在屏幕上显示的方式声明视图,余下交由系统来创建所需的代码。但声明式语法不只用于组织视图,还可在应用状态发生变化时更新视图。
92 1
|
30天前
|
机器学习/深度学习 人工智能 自然语言处理
《解锁ArkTS模型封装与抽象:代码复用与维护的进阶之道》
在鸿蒙系统中使用ArkTS开发时,高效管理和运用AI模型至关重要。通过封装和抽象,隐藏模型实现细节并提供简洁接口,能提升代码复用性、稳定性和可扩展性。封装使模型内部变化不影响外部调用,降低耦合度;抽象提取共性操作,简化代码结构。这不仅提高开发效率,还增强代码可维护性和团队协作效率,为复杂智能应用奠定基础。
53 21
|
9月前
|
存储 安全 Swift
【Swift开发专栏】Swift的懒加载与延迟初始化
【4月更文挑战第30天】Swift中的懒加载和延迟初始化是性能优化的关键技术。懒加载(lazy)推迟了变量直到首次访问时的初始化,减少启动时间和内存消耗。延迟初始化则允许变量在首次访问前保持未初始化状态。这两种方法都能提升应用性能,减少不必要的资源加载,并提高代码组织性。但要注意线程安全、资源管理以及代码可读性。
287 0
|
9月前
|
编译器 API Swift
【Swift开发专栏】Swift中的SwiftUI框架初探
【4月更文挑战第30天】SwiftUI是苹果2019年推出的界面构建框架,简化iOS应用开发。通过声明式语法和编译器优化,提供直观高效的UI设计。本文将介绍SwiftUI概述、主要特性及实际案例。SwiftUI强调“少即是多”,用少量代码实现复杂界面,提供简洁API、自动布局、双向数据绑定等功能。通过视图组合和实时预览加速开发。案例展示如何用SwiftUI构建用户列表界面,体现其结构清晰、易扩展的优势。SwiftUI在iOS开发中的重要性日益提升。
126 0
|
9月前
|
开发工具 Swift iOS开发
利用SwiftUI构建动态用户界面:iOS开发新范式
【4月更文挑战第3天】 随着苹果不断推进其软件开发工具的边界,SwiftUI作为一种新兴的编程框架,已经逐渐成为iOS开发者的新宠。不同于传统的UIKit,SwiftUI通过声明式语法和强大的功能组合,为创建动态且响应式的用户界面提供了一种更加简洁高效的方式。本文将深入探讨如何利用SwiftUI技术构建具有高度自定义能力和响应性的用户界面,并展示其在现代iOS应用开发中的优势和潜力。
|
9月前
|
API iOS开发 UED
SwiftUI 设计
SwiftUI 设计
94 2
|
9月前
|
存储 Go vr&ar
大师学SwiftUI第6章 - 声明式用户界面 Part 2
控件是交互工具,用户通过交互修改界面状态、选取选项或插入、修改或删除信息。我们实现过其中的一部分,如前例中的Button视图以及TextField视图。要定义一个有用的接口,需要学习有关视图的更多知识以及其它由SwiftUI所提供的控制视图。
66 0
|
9月前
|
存储 安全 vr&ar
大师学SwiftUI第6章 - 声明式用户界面 Part 3
SwiftUI还内置了创建安全文本框的视图。这一视图会把用户输入的字符替换成点以及隐藏敏感信息,比如密码。 •
73 0
|
9月前
|
存储 vr&ar Swift
大师学SwiftUI第6章 - 声明式用户界面 Part 4
Stepper视图创建一个带递增和递减按钮的控件。该结构体提供了多个初始化方法,包含不同的配置参数组合。以下是最常用的一部分。 •
67 0
|
前端开发 数据库
MVVM框架代码逻辑整合
MVVM框架代码逻辑整合
119 0