在界面开发过程中,我们常常可以看到一个页面会有很多UI控件组成,例如:文字和图片上下排列、左右排列,或者文字在图片中间。这些所谓的排列,我们可以统称为堆栈。
在本章中,你将学会如何使用堆栈视图,分为VStack垂直视图、HStack水平视图、ZStack覆盖视图。
VStack:视图垂直排列;
HStack:视图横向排列;
ZStack:视图覆盖排列;
下面的图例可以快速帮助理解和记忆这三个视图:
下面我们来试试完成下面的UI示例的编程。
首先,我们先创建一个新项目,命名为SwiftUIStacks。
我们先把UI图拆解成两个部分:标题、付费方案。
首先是标题部分,如下原型所示:
标题部分由两个Text组成,分别是Text(“会员套餐”)、Text(“解锁高级功能”)。
两个Text是上下排列,我们使用VStack{},把两个Text“包裹”在一起。
标题可以再加点样式进行美化,比如:字重、文字大小等等。
VStack { Text("会员套餐") .fontWeight(.bold) .font(.system(.title)) Text("解锁高级功能") .fontWeight(.bold) .font(.system(.title)) }
Stack默认视图为居中对齐,如果我们像像UI稿一样左对齐,那么我们可以在VStack纵向视图中加入alignment参数。
另外,我们想要两个Text之间的能够撑开一点,可以使用spacing参数设置间距。
参数 | 名称 | 描述 |
alignment | 居中方式 | .leading左对齐,.trailing右对齐,.center居中 |
spacing | 间距 | 间隔,组件之间的间隔距离 |
VStack(alignment: .leading,spacing: 10) { Text("会员套餐") .fontWeight(.bold) .font(.system(.title)) Text("解锁高级功能") .fontWeight(.bold) .font(.system(.title)) }
好的,我们已经完成了标题的部分啦!
我们发现标题和下面的定价方案是上下排列,那么我们可以先用一个VStack包裹起来。
特别说明:组件之间缺少Stack包裹,那么系统是不知道它是什么排列方式的,会报错。
鼠标移动到VStack的位置,键盘按住command键,单击鼠标,我们可以看到Xcode提供了快捷动作的编程方式。
我们选择Embed in VStack,那么我们在之前VStack外面会再包裹一层VStack。
这样做的好处是,我们常常编程时,代码多的情况下会不知道“{}”是包裹什么代码的,或者漏了末尾的“}”。
在这里我们可以先备注下Stack包裹的代码块,便于我们找到代码块的起始位置和终止位置。
VStack { //标题 VStack(alignment: .leading,spacing: 10) { Text("会员套餐") .fontWeight(.bold) .font(.system(.title)) Text("解锁高级功能") .fontWeight(.bold) .font(.system(.title)) } //定价方案 }
下面我们来做付费方案的部分。
先分析下UI稿,我们可以看到有3个定价方案,我们看到的尺寸大小基本是一致的,使用HStack横向排布的方式。
我们先做单个定价方案的样例,再复制其他2个,修改下颜色就行了。
在这里我们先忽略“首月特惠”的样式,因为这块用到了ZStack,那么这块先放在最后。
分析下单个定价方案,我们发现由Text(“连续包月”)、Text(“¥18”)组成,我们依旧可以用VStack纵向排列。
在这个VStack外,我们可以看到它有撑开的部分.padding,背景颜色.background,还有圆角.cornerRadius修饰。
// 定价方案 VStack { Text("连续包月") .fontWeight(.bold) .font(.system(size: 17)) .foregroundColor(.gray) Text("¥18") .fontWeight(.bold) .font(.system(size: 30)) .foregroundColor(.red) } .padding(20) .background(Color.orange) .cornerRadius(10)
代码运行后发现,和UI稿还是有点差距的,这是因为使用的系统颜色与UI设计稿的颜色相差甚远。
我们需要使用和UI设计稿一样的颜色,设置颜色的方式有2种,一种是使用RGB颜色值,一种是在Assets.xcassets文件中导入颜色再引用。
使用RGB颜色值方法如下:
// 定价方案 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)) } .padding(20) .background(Color(red: 250/255, green: 247/255, blue: 243/255)) .cornerRadius(10)
导入颜色的方法如下:
点击Assets,在底部点击“+”按钮,选择Color Set(或者鼠标右键)。
为方便记忆,我们可以使用颜色值作为命名,也可以用其他便于记忆的命名。
选中Any Appearance,这是默认的颜色,Dark为黑夜模式下的颜色,Apple要求上架的应用必须适配黑夜模式。
点击左侧顶部“设置”页,点击Color下的Show Color panel,这时会打开颜色选项弹窗。
我们可以设置RGB颜色,也可以使用Hex颜色设置,这里我们设置Hex Color 为faf7f3。
我们回到ContentView.swift文件,把VStack的背景颜色改成Color(“faf7f3”),在Color()中输入我们之前导入的颜色名称。
这样我们就可以引用录入的颜色了。
两种方式在实际业务开发中都可以使用,主要看个人习惯,没有优劣之分。
让我们回到定价方案的编程。
我们可以看到连续包月的定价方案有一个圆角的边框,我们可能会想到之前在Text中学到的.border()参数。
那先看看效果。
// 定价方案 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)) } .padding(20) .background(Color("faf7f3")) .border(Color(red: 202/255, green: 169/255, blue: 106/255),width: 2) .cornerRadius(10)
首先科普一个知识点。
在编程区中不难发现,我们把.border()代码放在了.cornerRadius(10)前面。
这是因为SwiftUI语言中,修饰符是顺序执行的,也就是我们是先有边框,才把边框编程10度的圆角。
如果先有圆角,再有边框,那么我们就会得到里面的撑开的颜色是圆角的,但边框是直角的,不妨试试效果。
另外一点,我们看到模拟器中,圆角边框缺失了4个角。
这是因为SwiftUI默认为maskToBounds,所以这种方式设置的圆角会被裁剪一部分。
这时我们不能用这种方式设置,我们可以使用之前学过的.overlay()修饰符“覆盖”一个圆角。
// 定价方案 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)) } .padding(20) .background(Color("faf7f3")) .overlay(RoundedRectangle(cornerRadius: 6).stroke(Color(red: 202 / 255, green: 169 /
代码.overlay(RoundedRectangle(cornerRadius: 6).stroke(Color(red: 202 / 255, green: 169 / 255, blue: 106 / 255), lineWidth: 2)看起来特别长,不用担心,我们理解下它。
RoundedRectangle():圆角矩形;
cornerRadius:圆角度数;
stroke:描边;
Color:颜色;
lineWidth:线度;
用自然语言来阅读下代码:给这个视图加一个圆角,再给圆角描个有颜色的线框。
好了,我们完成了第一个定价方案的编程啦!