
1.3 创建卡片视图布局
在本节中,我们将为项目创建一个卡片视图。
1.3.1 创建CardView
在项目导航中右击FirstApp条目(黄色图标的),在弹出的快捷菜单中单击“New File...”,然后在弹出的文件模板对话框中选择iOS/User Interface/SwiftUI View类型,并将新建文件命名为CardView。
作为一名优秀的程序员,对源代码添加必要的注释是一个非常好的习惯,我们需要对CardView文件的三个地方添加注释语句。


几乎每个SwiftUI类型的初始文件都会包含3个Mark的部分,Properties部分用于放置属性,Body部分是SwiftUI中最关键的部分,我们所有的视图设计与布局都是在这里完成编码的,最终呈现到设备屏幕上的。Preview部分用于让开发者在Xcode中实时查看界面的布局效果。
现在,我们可以在Xcode编辑区域的预览窗口中查看CardView布局效果,如果没有看到,那么可以单击右上角的Resume按钮重新生成,如图1-13所示。

图1-13 在预览窗口中查看CardView效果
修改CardView的Body部分代码如下。

最新版本的SwiftUI有用于创建前后重叠内容的专用堆栈类型容器ZStack。如果我们想在图片上放置一些文本,那么它会非常有用。与其工作方式类似的还有横向(HStack)与纵向(VStack)堆栈容器。在默认情况下,ZStack的对齐方式为中心对齐。
在上面的代码中,我们还为ZStack添加了几个修饰器,frame用于设置容器的像素为335×545,该容器的背景是粉色视图,针对粉色的背景视图设置了圆角和阴影,效果如图1-14所示。

图1-14 在预览窗口中查看CardView的最终效果
接下来,我们需要将CardView嵌入ContentView中,因为在预生成的项目模板中,应用程序总是从ContentView开始运行的,我们会在ContentView中嵌入CardView。
在项目导航中打开ContentView.swift文件,一如既往地在三个位置添加Properties、Body和Preview注释语句。
修改Body部分的代码如下。

在ContentView的Body部分,我们嵌入了CardView。这样,在应用程序的启动画面消失以后,就会看到一个粉色的卡片了。
当然,苹果公司发展到现在已经有了各种不同型号和尺寸的iPhone、iPad产品,为了方便我们在预览窗口中查看视图在不同尺寸产品中的呈现效果,还可以在Preview部分指定产品型号,修改Preview部分的代码如下。

这里我们为ContentView添加了previewDevice修饰器,修饰器的参数为设备名称,例如iPhone 11 Pro Max、iPhone 12和iPad Pro(9.7-inch)等。
除了可以通过previewDevice修饰器设置预览设备型号,我们还可以利用previewLayout修饰器设置预览方式。打开之前的CardView,因为我们只把它当作一个可复用,并且会被嵌套到程序主视图中的小视图使用,所以在预览的时候,可以将它的Preview部分代码修改成下面这样。

利用previewLayout修饰器,可以设置预览方式,参数sizeThatFits代表预览窗口的尺寸与实际呈现视图的尺寸一致,也就是说布局的界面有多大,预览窗口的尺寸就有多大,它与设备无关,如图1-15所示。

图1-15 设置CardView预览方式为sizeThatFits
1.3.2 创建线性渐变色背景
接下来,我们为CardView创建一个线性渐变色背景。首先需要在CardView的Properties部分添加相关属性。

变量gradient是Color类型的数组,里面包含两个颜色元素,其中Color01和Color02是我们在1.1节中向Assets.xcassets里面添加的颜色集素材。
在Body部分,将ZStack的background修饰器修改为下面这样。

我们称LinearGradient为线性渐变。在SwiftUI中,实现线性渐变非常简单,只需提供三个参数:颜色数组、起点和终点。这里通过Gradient初始化方法生成渐变颜色集,然后指明视图的顶部为起点颜色(Color01定义的颜色),视图的底部为终点颜色(Color02定义的颜色),在预览窗口的效果如图1-16所示。

图1-16 为CardView设置线性渐变色背景的效果
1.3.3 为CardView添加图像和文本
在创建好线性渐变色背景以后,就该为卡片添加图像了,继续修改Body部分的代码。

这里将之前的Text替换为Image,使用之前在Assets.xcassets中添加的开发人员图片素材,在预览窗口中查看效果,如图1-17所示。

图1-17 为CardView添加图像素材之后的效果
接下来,我们需要在卡片上添加文字说明,修改Body部分的代码为下面这样。

在ZStack容器中,除了Image,还添加了一个VStack容器,我们用它布局上下排列的两个Text文本。第一个文本使用font修饰器设置字体,使用fontWeight设置文字的粗细,使用foregroundColor设置文字颜色,使用multilineTextAlignment设置多行文本的对齐方式。第二个文本则使用italic修饰器设置文本倾斜。
最后,为VStack容器添加offset修饰器,将VStack容器在父视图中的位置纵向上移218点。因为ZStack容器中的所有视图都是居中对齐的,所以在水平位置上不用做任何调整。在预览窗口中的效果如图1-18所示。

图1-18 为CardView添加文字之后的效果
1.3.4 为CardView添加按钮
我们还需要在卡片的底部添加一个按钮,利用SwiftUI提供的Button结构体直接创建就好,在VStack容器的下面添加如下代码。


Button包含两个参数,action参数是用户单击按钮以后执行的代码。Button尾部的闭包则用于设置按钮的外观,该按钮为一个文本,Text的accentColor修饰器用于设置按钮的强调色。如果不设置强调色,那么它会显示默认的蓝色。Button的offset修饰器用于将按钮的位置下移210点,在预览窗口中的效果如图1-19所示。

图1-19 为CardView添加按钮之后的效果
接下来,我们需要为按钮添加一个图标,这样对于用户才更有吸引力。苹果公司在2019年的WWDC期间推出了SF符号(SF Symbols),这对开发者来说是一个很大的礼物,因为在应用程序中,我们可以免费使用这些符号。到了2020年的WWDC时,苹果公司又引入了SF符号2.0版本,它提供了更多、更精美的图标供我们使用。
SF符号已经被集成到苹果的San Francisco系统字体之中,支持的平台有iOS 13及更高版本,watchOS 6及更高版本,tvOS 13及更高版本,以及Mac应用程序。SF符号2.0在1.0的基础上,新增了750多种符号,包括设备、健康状况、运输符号等。但是新符号仅在iOS 14、iPadOS 14和macOS Big Sur版中可用。
另外,苹果提供了SF符号应用程序,可以让我们浏览、复制和导出任何可用的符号。该应用程序可在苹果公司官方网站下载。安装并运行后,界面如图1-20所示。

图1-20 SF符号应用程序界面
在SF符号应用程序中右上角的搜索栏中输入arrow关键字,在所有与箭头相关的图标中找到arrow.right.circle图标,然后在编辑菜单中单击“拷贝1个名称”,这样就可以在iOS项目中使用它了。
回到CardView.swift文件之中,在Button闭包中Text外部嵌套一个HStack容器,并添加如下代码。

被HStack容器封装的Text的右侧为Image,systemName参数用于指明所调用的SF符号的名称,因为SF符号也属于字体,所以可以使用与字体相关的修饰器进行设置。
对于HStack容器的设置,首先利用padding修饰器将水平方向的间隔距离增加至系统默认的距离,再利用padding修饰器设置垂直方向的间隔距离为24点。在进行视图布局的时候,我们经常会通过连续使用两次padding修饰器来调整视图的布局效果,有时甚至会使用4次,因为你可能需要对4个方向的间隔距离分别设置不同的数值。
在调整好HStack容器的间隔距离以后,为其添加渐变色背景,与之前有一点儿小小的不同,这里的起点是leading,终点是trailing,也就是从左到右渐变。
clipShape修饰器用于将现有的长方形视图裁剪为指定的形状,这里设置为Capsule(),代表将HStack容器裁剪为两边为圆形的胶囊形状。
最后,我们为HStack容器添加阴影效果,阴影的颜色为ColorShadow,它是之前我们在Assets.xcassets中所定义的颜色集,黑色,透明度60%。在预览窗口中的效果如图1-21所示。

图1-21 CardView最终的界面布局效果
此时,回到ContentView中,在预览窗口中可以看到相同的界面布局效果。