![SwiftUI自学成长笔记](https://wfqqreader-1252317822.image.myqcloud.com/cover/983/41202983/b_41202983.jpg)
1.5 为卡片创建数据模型
本节我们将创建数据模型对象,有了这样的模型,就可以将真正的数据信息呈现到卡片上供用户浏览了。
1.5.1 创建卡片数据模型
在项目导航中添加一个新的Swift类型的文件,如图1-24所示,将文件命名为CardModel。
![](https://epubservercos.yuewen.com/CE38D5/21440188008281406/epubprivate/OEBPS/Images/41822_39_1.jpg?sign=1738866193-hl6bK36dJCtLxSCKu6nfRQCzKSbPEdeZ-0-6db4afee3a0c1e1f5216476bb8a72528)
图1-24 在文件模板对话框中选择Swift类型文件
文件创建好以后就可以为卡片的所有关键信息创建数据模型了,代码如下。
![](https://epubservercos.yuewen.com/CE38D5/21440188008281406/epubprivate/OEBPS/Images/41822_39_2.jpg?sign=1738866193-NdCVPhfCBIAGQRLAz3vaOcT8zPTKPrCA-0-b7fa0e667c6b6d7b0ec27339bc84b3c4)
这里使用结构体(Struct)定义卡片的数据模型,在该结构体中会用到SwiftUI框架中的Color结构体,所以一定要将之前的Foundation框架替换为SwiftUI框架。
需要注意的是,因为该结构体要符合Identifiable协议,也就是通过该结构体被实例化的每个对象都必须是唯一的、可标识的,所以必须在结构体中包含一个id属性,并且id属性的值也必须是唯一的、可标识的。因此这里使用UUID()函数的值作为id的值,UUID()函数会随机生成一个唯一的值。
然后,我们在结构体中定义卡片的标题、内容提要、图片文件名、按钮标题、相关信息、背景渐变色。gradientColors是Color类型的数组,之前在Assets.xcassets中我们一共添加了14种不同的颜色集,这里就利用它们生成线性渐变色背景。
在CardModel结构创建完成以后,我们还需要添加一个新的文件存储真正的人物资料数据。
1.5.2 为静态数据创建数组
接下来,我们需要创建供CardModel使用的数据信息。因为这一章是本书的起始章节,所以我们会使用最简单、最容易实现的方式来组织这些数据。之后,随着学习的不断深入,我们会使用更为专业的方法。
我们需要在新的Swift文件中创建数组。所以先在项目导航中创建一个新的Swift类型文件,将其命名为CardData。需将文件中的代码修改为下面这样。
![](https://epubservercos.yuewen.com/CE38D5/21440188008281406/epubprivate/OEBPS/Images/41822_40_1.jpg?sign=1738866193-nkP12j5zhjG7aq8M4ELhD38tBeuMnRro-0-964b24129f99ee6021e10c9602c08d6d)
现在,我们已经为cardData数组添加了一个Card类型的元素对象,如果你愿意,那么还可以继续添加其余的6个元素,或者直接复制已经提供好的数据。在“项目资源/Data”中,将CardData.txt文件中的所有数据复制到let cardData:[Card]=[]数组中即可。
1.5.3 在卡片中显示数据信息
本节的主要任务是将数据呈现在卡片上,在对CardView的代码进行调整之前,先注释掉ContentView中ForEach里面对CardView()的调用。
![](https://epubservercos.yuewen.com/CE38D5/21440188008281406/epubprivate/OEBPS/Images/41822_40_2.jpg?sign=1738866193-8H02IqTUk6MranfD15GUiTdqTpg3Osgd-0-e81376f677729d04b979346051edd19d)
之所以这样做,是因为接下来我们会在CardView中添加属性,新添加的属性会改变CardView的调用方式,如果沿用之前的方式,编译器就会报错,影响我们的测试。
接下来,在项目导航中选择CardView.swift文件,为该结构体添加一个属性,代码如下。
![](https://epubservercos.yuewen.com/CE38D5/21440188008281406/epubprivate/OEBPS/Images/41822_41_1.jpg?sign=1738866193-2QzfGPORLRo4eZEimEM9l1P1VzzPfVFO-0-32286694e2bbf56e7221dbcd25ff1c5c)
你可能会注意到,此时在Xcode的顶部会出现一个红圈叉报错,编译器此时会停止工作。导致错误的原因是在Preview部分,我们没有在实例化CardView()的时候为card变量赋值。
要想快速修复这个错误,可以单击错误行右侧的红色圆点,然后在错误描述面板中单击Fix即可,如图1-25所示。
![](https://epubservercos.yuewen.com/CE38D5/21440188008281406/epubprivate/OEBPS/Images/41822_41_2.jpg?sign=1738866193-hS8x8LhrgPjwmYjU6eq245jYm7sgt7bm-0-fbd07a171d1f5818da0c45549af8d294)
图1-25 快速修复未初始化属性的错误
此时,我们需要为CardView()提供一个Card类型的对象参数。之前在CardData中已经创建好了cardData数组,因此,这里只需要提供给它数组中的一个元素即可。将报错行修改为CardView(card:cardData[1]),Xcode顶端的红圈叉消失,编译器又开始正常工作了。
接下来就要修改Body部分的代码了,因为之前我们都是手动将信息强行写入代码中的,所以现在需要将这部分代码全部修改为card变量的形式,修改代码如下。
![](https://epubservercos.yuewen.com/CE38D5/21440188008281406/epubprivate/OEBPS/Images/41822_41_3.jpg?sign=1738866193-vMGhPYolj8C89lT6X7AHCDVRkzuFt8nm-0-32579d4fc7be24898df084c8c9c90936)
![](https://epubservercos.yuewen.com/CE38D5/21440188008281406/epubprivate/OEBPS/Images/41822_42_1.jpg?sign=1738866193-RFAOtkhDNGrycZ4mCCrwieQZYpOJ6lYu-0-e6c7f17cab706ba68bb3636b290db4e8)
这里我们一共修改了6处,调用的是Card对象的5个属性:title、headline、imageName、callToAction和gradientColors。为了验证是否成功,可以修改Preview部分cardData数组的索引值,看看是否更新了不同的人物信息,如图1-26所示。
![](https://epubservercos.yuewen.com/CE38D5/21440188008281406/epubprivate/OEBPS/Images/41822_42_2.jpg?sign=1738866193-z4DHGXucUblubxvGqw84FqTYL6vTTUTY-0-500c27fd5ec6d1b7c2185870306de662)
图1-26 7张不同的人物卡片效果
这时,让我们回到ContentView,如同CardView一样,在Properties部分添加一个新的属性。
![](https://epubservercos.yuewen.com/CE38D5/21440188008281406/epubprivate/OEBPS/Images/41822_42_3.jpg?sign=1738866193-ShBVwg0kHeV7s9fxFyJGRpj86TGIl5JM-0-7cde096c6dec9b6c0eb567026a513a13)
![](https://epubservercos.yuewen.com/CE38D5/21440188008281406/epubprivate/OEBPS/Images/41822_43_1.jpg?sign=1738866193-K2tMPpwgerC6sPzWAh4Vwe7lCLrbNmHa-0-d5f054de68ebeb6d04ac5e697cf969ed)
因为cards数组中的元素均符合Identifiable协议,所以在ForEach循环中可以直接通过cards遍历数组中的每个元素信息。此时的item代表的就是cards数组中的元素,因此可以将其作为参数传递给CardView。
构建并在模拟器中运行该项目,效果如图1-27所示。
![](https://epubservercos.yuewen.com/CE38D5/21440188008281406/epubprivate/OEBPS/Images/41822_43_2.jpg?sign=1738866193-QwlYlxEoJv9ZjxXd6NCIqbRDb9pkVOd2-0-e91972b3b67cfc113f576f20842f40e7)
图1-27 在模拟器中运行的效果