Create a custom data model for Todo items in SwiftUI | Todo List #2

Swiftful Thinking
15 Mar 202111:46

Summary

TLDR在这段视频脚本中,Nick介绍了在MVVM架构中创建和实现模型(Model)的过程。他们以待办事项列表应用为例,展示了如何构建一个自定义数据类型来表示待办事项。这个模型不仅包含事项的标题,还包含一个唯一标识符(ID)和一个布尔值(isCompleted),用以标记事项的完成状态。Nick还解释了如何让模型符合SwiftUI中的Identifiable协议,以便于在ForEach循环中使用,并演示了如何更新ListView和ListRowView来显示带有完成状态的待办事项。视频最后,Nick预告了下一集将介绍ViewModel,用于添加、删除和更新待办事项的逻辑。

Takeaways

  • 📝 **模型定义**:在MVVM架构中,'Model'代表数据模型,用于定义应用程序的数据结构和状态。
  • 📚 **自定义数据类型**:创建自定义数据类型(Model)来表示待办事项列表中的项目,包含标题、唯一标识符和完成状态。
  • 🔍 **属性细节**:待办事项除了标题外,还应包含一个唯一ID和布尔值来标识是否完成。
  • 🏗️ **简化生产应用**:虽然示例中的模型相对简单,但足以学习如何构建和有效实现模型。
  • 📑 **Xcode项目**:在Xcode项目中创建一个新的模型组,并添加一个Swift文件来定义模型。
  • 🔑 **唯一标识符**:为每个待办事项添加一个唯一ID,使用UUID生成随机字符串。
  • 🔄 **符合协议**:使模型符合`Identifiable`协议,以便于在SwiftUI的`ForEach`循环中使用。
  • 🎨 **动态UI**:根据待办事项的完成状态动态显示不同的UI元素,如红色圆圈表示未完成,绿色勾选表示已完成。
  • 📝 **初始化器**:创建一个初始化器,要求提供标题和完成状态,但最终移除了ID的初始化,因为每个项已经有ID。
  • 📱 **预览自定义**:在SwiftUI的预览中使用静态变量来展示不同的待办事项状态。
  • 🌟 **字体与颜色**:调整字体大小和颜色,使已完成的事项显示绿色,未完成的显示红色。
  • 🔧 **ListView更新**:更新ListView,使用ListRowView展示每个待办事项,并根据其完成状态显示不同的图标和颜色。

Q & A

  • 在Swift UI中,如何改变ListView中项的字体大小?

    -可以通过在HStack中使用.font(.title2)来改变ListView中项的字体大小。

  • 在接下来的视频中,将会介绍MVVM架构中的哪个部分?

    -在接下来的视频中,将会介绍MVVM架构中的ViewModel部分,这涉及到添加、删除和更新待办事项的逻辑。

Outlines

00:00

📝 构建模型

在本段中,介绍了MVVM架构中的'M',即模型(Model)的概念。视频中的目标是创建一个自定义数据类型,用于表示待办事项列表应用中的待办事项。每个待办事项将包含一个标题、一个唯一标识符ID以及一个布尔值来表示事项是否已完成。虽然在生产级应用中模型可能更复杂,但本例旨在教授如何构建模型并有效实现到应用中。在Xcode项目中,通过创建一个新的模型组和文件,定义了一个名为'ItemModel'的结构体,它包含标题(title)、完成状态(isCompleted)和唯一标识符(id)。为了在SwiftUI的forEach循环中使用,'ItemModel'还遵循了'Identifiable'协议。

05:01

🔍 更新数组和视图

在第二段中,作者从使用字符串数组更新为使用'ItemModel'数组来存储待办事项。通过创建几个'ItemModel'实例,展示了如何初始化待办事项的标题和完成状态。同时,由于'ItemModel'遵循了'Identifiable'协议,因此不再需要显式地为每个待办事项创建一个ID。接下来,作者修改了列表行视图(ListRowView),使其接受'ItemModel'类型的参数,并更新了文本和预览以反映待办事项的状态。此外,还介绍了如何在预览中使用静态变量来展示不同的待办事项状态,并使用三元运算符和条件颜色来根据待办事项的完成状态显示不同的图标和颜色。

10:02

🎨 完成列表视图样式

第三段主要关注于完成列表视图(List View)的样式设计。作者通过调整字体大小、颜色和添加一些内边距,使得列表行(List Rows)的外观更加吸引人且具有动态性,能够根据待办事项的完成状态变化显示不同的视觉元素。最后,作者回顾了整个视频的内容,包括创建'ItemModel'、将其实现到视图中,并预告了下一视频中将介绍的视图模型(View Model),它将包含添加、删除和更新待办事项的逻辑。

Mindmap

Keywords

💡MVVM

MVVM是Model-View-ViewModel的缩写,是一种软件架构模式,用于构建和组织用户界面。在视频中,MVVM用于指导如何构建一个待办事项列表应用程序,其中Model代表数据模型,View代表用户界面,ViewModel作为数据和界面之间的桥梁,处理数据和界面的交互逻辑。

💡Model

在MVVM架构中,Model指的是应用程序中用于数据存储和操作的组件。视频中,Model用于创建自定义数据类型,用于表示待办事项列表中的每个条目,包含标题、唯一标识符和完成状态。

💡待办事项列表

待办事项列表是一种常用的应用程序,用于帮助用户跟踪和管理他们需要完成的任务。视频的主题是构建一个待办事项列表应用程序,其中展示了如何使用MVVM架构来设计和实现该应用程序。

💡自定义数据类型

自定义数据类型是指开发者根据特定需求创建的数据结构,它包含了一组特定的属性和可能的行为。在视频中,为了表示待办事项,创建了一个自定义数据类型,称为Item Model,它包含了标题、唯一标识符和完成状态。

💡唯一标识符(ID)

唯一标识符(ID)是一个用于区分不同数据记录的值,确保每个待办事项条目都可以被独立识别。视频中的Item Model包含一个ID属性,使用UUID生成,以确保每个待办事项都有唯一的标识。

💡布尔值(Boolean)

布尔值是一种逻辑数据类型,只有两个可能的值:真(true)和假(false)。在视频中,使用布尔值来表示待办事项是否已完成,其中`isCompleted`属性就是布尔类型,用来存储每个待办事项的完成状态。

💡Swift

Swift是一种由苹果公司开发的强类型、编译型编程语言,主要用于iOS、macOS、watchOS和tvOS应用程序的开发。视频中使用Swift语言来构建待办事项列表应用程序的Model。

💡Xcode

Xcode是苹果公司开发的集成开发环境(IDE),用于开发macOS、iOS、watchOS和tvOS的应用程序。视频中的开发者使用Xcode项目来创建和管理待办事项列表应用程序的代码。

💡SwiftUI

SwiftUI是一个由苹果公司提供的用于构建用户界面的框架,它允许开发者以声明式的方式创建应用程序的界面。视频中提到了SwiftUI,尤其是在创建和展示待办事项列表的界面时使用。

💡可识别(Identifiable)

在SwiftUI中,Identifiable是一个协议,它要求类型有一个唯一的标识符。这使得在列表中的数据项可以被独立识别和更新。视频中的Item Model遵循了Identifiable协议,以便于在SwiftUI的ForEach循环中使用。

💡初始化器(Initializer)

初始化器是编程中的一个概念,用于创建类的实例或结构体的实例,并在创建时设置其初始状态。在视频中,Item Model有一个初始化器,它接收标题和完成状态作为参数,用于创建新的待办事项条目。

💡列表行视图(List Row View)

列表行视图是用户界面中的一个组件,用于在列表中显示单个条目的信息。在视频中,开发者创建了一个自定义的列表行视图,用于展示待办事项的标题、完成状态和唯一标识符。

Highlights

MVVM架构中Model的创建,用于定义待办事项列表应用的数据模型

待办事项列表项将包含标题、唯一ID和完成状态

生产级应用中模型通常比示例更复杂,但本示例适合学习模型构建

在Xcode项目中创建一个新的模型组和文件,命名为ItemModel

ItemModel结构包含标题(title)和完成状态(isCompleted)

为了在SwiftUI的ForEach循环中使用,ItemModel需要符合Identifiable协议

ItemModel添加唯一标识符ID,使用UUID生成

初始化ItemModel时需要提供标题和完成状态

将数组中的字符串替换为ItemModel对象数组

由于ItemModel符合Identifiable,不再需要显式提供ID

更新ListView中的ListRow视图以使用ItemModel对象

使用Preview Provider创建静态的ItemModel对象以供预览使用

根据ItemModel的完成状态动态显示不同的图标和颜色

调整字体大小和添加边距以改善ListRow视图的显示效果

ListView现在可以根据ItemModel的完成状态显示不同的视觉反馈

接下来的视频中将添加ViewModel,实现添加、删除和更新待办事项的逻辑

应用正在逐步构建成型,提供了一个动态且响应式的待办事项列表界面

Transcripts

play00:00

[Music]

play00:05

all right

play00:06

so the first m in mvvm stands for model

play00:10

and that's what we're doing in this

play00:12

video so what we're going to do is build

play00:14

a model which is basically a custom

play00:16

data type for our to-do list app we're

play00:19

going to use a model

play00:21

for the to-do list items because our

play00:23

to-do list items are going to have more

play00:25

than just

play00:25

a title they're also going to have a

play00:27

unique id

play00:29

as well as an is completed boolean so

play00:31

that we can determine

play00:32

whether or not the to-do item is

play00:34

completed or not

play00:36

now of course when you build

play00:38

production-ready apps

play00:39

a lot of times the model is going to be

play00:41

much more complicated than what we're

play00:43

doing here

play00:44

but this example is going to be perfect

play00:47

for you to learn how to build models and

play00:50

then how to implement them

play00:51

into your app effectively so with that

play00:54

said

play00:54

let's take a look so i am back in our

play00:57

xcode project

play00:58

of course and in this video we're going

play01:01

to look at

play01:02

the model so the model is going to be

play01:04

the custom data point that we have

play01:07

for each of our to-do list items

play01:10

and if we look right now if we go into

play01:12

the list view which is where i'm at

play01:14

right now we have the list and we're

play01:16

looping on a bunch of items and the

play01:18

items

play01:18

is an array of string and this is great

play01:21

because as we can see in the preview we

play01:23

can change the title for each item

play01:25

but there's more information here that

play01:26

we want to include for each of these

play01:28

items

play01:29

and the main thing that comes to my mind

play01:31

is whether or not this item is completed

play01:34

because right now we have the check mark

play01:35

on all three of these but sometimes when

play01:37

we add items to our to-do list

play01:39

they're not completed so we don't want

play01:41

them to have a check mark here

play01:44

and with the current setup right now

play01:46

with this array of strings we can't

play01:48

actually add

play01:49

additional data into this we can't

play01:51

determine whether or not this item this

play01:54

string right here is completed or not

play01:57

so by making a custom model we can

play01:59

create a data type

play02:00

that has both the title as well as a

play02:05

boolean for whether or not it is

play02:06

completed so let's right click the

play02:08

navigator and create a new group

play02:10

and we're going to call this models

play02:14

so remember we're doing mvvm

play02:15

architecture so now we have m

play02:17

for model we have v for view and in the

play02:19

next video we'll do

play02:20

the view model but for right now right

play02:23

click the models

play02:24

create a new file and we're not going to

play02:27

use a preview in this file so

play02:29

instead of doing swift ui view like we

play02:31

always do let's use just a regular swift

play02:34

file go ahead and click next and i'm

play02:37

going to call this

play02:38

item model

play02:41

go ahead and click create

play02:44

this will be a struct and we're going to

play02:46

call it item

play02:47

model and we're going to open the

play02:49

brackets

play02:51

and you don't have to include the word

play02:53

model effort but i like to

play02:54

it is just a little helpful in

play02:56

clarifying that this is the model

play02:58

in our app there are two main things

play03:01

that we have in our model

play03:02

the first is the title so let's say let

play03:04

title of type

play03:06

string and the second is a

play03:09

boolean whether or not it is completed

play03:11

so we'll say let

play03:13

is completed and this will be of type

play03:16

bool so if it's complete well this will

play03:19

be true if it's not it will be

play03:21

false and this is pretty much it for our

play03:24

model

play03:25

but if you follow the swift ui bootcamp

play03:28

you

play03:28

are probably well aware that if we want

play03:31

to use this item model in a for each

play03:33

loop

play03:34

it's much more convenient to make it

play03:36

conform to identifiable

play03:38

so to do that all we're going to do is

play03:40

add a colon here and type

play03:41

identifiable so now our item model will

play03:44

conform to identifiable

play03:46

and in order to do that we just need to

play03:48

add an id

play03:49

into our item model so we'll say let

play03:52

id of type string

play03:55

and for right now we're going to set it

play03:56

equal to a random string so we're just

play03:58

going to set it equal to

play04:00

uuid open and close parenthesis

play04:03

this is a built in function that will

play04:04

create a random id

play04:06

and then we'll just call dot uuid string

play04:10

just to conform it to string because i

play04:12

like making these ids

play04:14

strings because strings are a little

play04:16

more flexible if we want to put them

play04:17

into like a third-party database or

play04:19

something like that

play04:21

so this is our whole model and in the

play04:23

initializer right now if we go to create

play04:24

an item model it's going to ask us

play04:26

for a title and for is completed status

play04:31

so now that we have this let's jump back

play04:33

into the list view

play04:36

and this items array instead of an array

play04:39

of string let's do an array of

play04:41

item model and i don't have it pulling

play04:44

up here on my autocomplete

play04:45

so i'm going to clean the build folder

play04:47

and we can do that by going up to

play04:49

product and clicking clean build folder

play04:52

but we could also do

play04:54

shift command k that will clean

play04:57

rebuild and now if i type in item model

play05:00

it should come up

play05:02

we have an array of item models so of

play05:04

course we don't need these anymore

play05:07

so let's delete these and instead we

play05:10

want item models so we'll do item

play05:12

model open the parentheses and now we

play05:14

have our

play05:15

initializer that we just made so it's

play05:17

looking for a title

play05:18

let's do this is the first title and

play05:22

is completed let's set it to false

play05:26

comma let's do another one item model

play05:29

title this is the second

play05:33

is completed let's set this one to true

play05:35

and then

play05:36

comma item model open the parentheses

play05:39

and let's just call it third and is

play05:43

completed i'll do

play05:44

false put a comma after it so now we

play05:46

have an array of

play05:48

three item models and we're getting this

play05:50

error here because since we need the

play05:52

since we're using this id here it's it

play05:55

wants our item model to conform to

play05:57

hashable

play05:58

but because we conformed to identifiable

play06:01

already

play06:02

remember in our item model we conform to

play06:04

identifiable with an id

play06:06

and each of these items have an id

play06:08

already we actually don't need

play06:10

this initializer so we could just delete

play06:13

this id

play06:14

backslash self and we can just loop on

play06:16

the items

play06:18

now we also need to update the list row

play06:19

view so i'm going to comment this out

play06:21

for a second

play06:23

and let's just put in a text of hi just

play06:25

to make this go

play06:26

the error go away for a second and let's

play06:29

jump into that list row view

play06:31

so list row view i'm going to click

play06:34

resume here

play06:38

and right now when we create a list row

play06:40

view we are passing in a title

play06:41

but of course we just built the model so

play06:44

let's actually pass

play06:45

in the item so we'll call it item and it

play06:48

will be of type

play06:49

item model and now our text instead of

play06:52

referencing a title we will reference

play06:54

item dot and we can see all the

play06:58

variables within an item model so it's

play07:00

that id the title and the is completed

play07:02

status

play07:03

so the title will be what our text is of

play07:06

course

play07:07

click resume and we actually need to fix

play07:10

the preview down here as well

play07:12

so what i'm going to do is create two

play07:14

item models that we can use in this

play07:16

preview so

play07:17

in this preview provider here so because

play07:21

we're working in the preview

play07:22

these variables need to be static which

play07:24

basically means that they

play07:26

will not change and you don't really

play07:28

need to worry about why we're using the

play07:29

word static here this is one of the only

play07:31

places we're going to use it

play07:32

at least for this video so let's do

play07:35

static

play07:36

var item 1 and let's set it equal to

play07:39

item

play07:39

model and let's just make the title

play07:42

first item you can make it whatever you

play07:45

want and is completed we'll do

play07:47

false let's create another variable here

play07:50

we'll do static

play07:51

var item 2 and we'll set this equal to

play07:54

item

play07:55

model and we'll do second

play07:58

item is completed we'll do true

play08:01

just so they have different is completed

play08:03

statuses and in our preview here

play08:07

let's delete this and we'll add a group

play08:10

and in our group and we're doing a group

play08:12

so that we can have two separate

play08:13

previews we can preview

play08:15

uh this list row view with the first

play08:17

model and the list row view with the

play08:19

second model so we'll do list row view

play08:23

open parenthesis and we're going to pass

play08:25

in item one

play08:26

and again do list row view open the

play08:29

parentheses and we're going to pass in

play08:30

item two click try again on the preview

play08:34

and we should now see our two item

play08:36

models

play08:37

and because we're in this group and we

play08:38

have two separate previews they're

play08:40

building on two different iphones so the

play08:42

first one's up here

play08:43

and the second one is down here but

play08:46

these

play08:47

listro views are very small so we don't

play08:49

actually need to see it on the entire

play08:51

iphone

play08:52

so what we'll do is call dot preview

play08:55

layout

play08:56

dot size that fits and this will change

play08:58

each preview to the smallest size

play09:00

that fits our entire list row view so

play09:03

now we can see the first item and the

play09:05

second item

play09:06

and let's customize these a little tiny

play09:09

bit

play09:09

the first thing that comes to mind is

play09:11

that we only want the check mark if it

play09:12

is completed

play09:13

so right now the first one is not

play09:15

completed and it shouldn't have a check

play09:16

mark

play09:17

so we're going to use a ternary operator

play09:20

and we'll say

play09:21

item dot is completed question mark so

play09:24

if it is completed

play09:25

let's use check mark dot circle

play09:27

otherwise

play09:28

let's just use circle

play09:36

so already on the preview you can see

play09:37

that that first one does no longer

play09:40

has a check mark in it and the second

play09:41

one it still has the check mark in it

play09:43

that's because the first one is false

play09:45

the second one is true let's also change

play09:47

the colors

play09:48

based on that so we'll do dot foreground

play09:50

color

play09:51

item dot is completed question mark if

play09:54

it's completed

play09:55

let's do color.green because that

play09:57

signals

play09:58

good otherwise we'll do dot red

play10:01

so the first one is now red the second

play10:04

one is green

play10:05

let's make them a little bit bigger by

play10:06

calling dot font and let's do maybe

play10:08

title two and i put it down here at the

play10:12

bottom of the h stack so that

play10:13

both the text and the image are updated

play10:16

with this font

play10:17

and let's wrap this up with just a

play10:19

little bit of padding on the

play10:21

vertical axis and we'll add maybe eight

play10:25

so that's it for a list review we now

play10:27

have our list rows

play10:29

looking really good and they are dynamic

play10:31

they'll change whether or not

play10:32

they are completed so we have the red

play10:35

circle we have the green check mark

play10:37

let's jump back into the list view

play10:40

we can get rid of our high we're going

play10:42

to get rid of the current list row view

play10:44

there

play10:44

and let's just type in list row view

play10:47

open the parentheses

play10:48

and it's looking for an item and of

play10:50

course we're already looping on an array

play10:52

of items because we have all of our

play10:54

items here so here i'll just pass in

play10:56

item and

play10:59

beautifully we can see all of our items

play11:01

in the list

play11:02

we have red circles for the

play11:04

non-completed green circles for the

play11:06

completed

play11:08

and this is starting to look like a real

play11:10

app

play11:11

uh now that's it for this video we

play11:13

created our item model

play11:15

we implemented the item model into our

play11:17

view and in the next video we're going

play11:19

to add the view model where we add a

play11:21

whole bunch of logic

play11:23

for actually adding deleting and

play11:25

updating all of these items

play11:27

it's gonna be a lot of fun i hope you

play11:29

guys are excited for it

play11:30

this app is really starting to come

play11:32

together as always

play11:34

i'm nick thank you for watching and i

play11:36

will see you

play11:37

in the next video

play11:42

[Music]

play11:45

you

Rate This

5.0 / 5 (0 votes)

Related Tags
模型构建待办事项数据类型界面设计MVVM架构Swift编程Xcode项目动态更新布尔逻辑自定义视图
Do you need a summary in English?