User Experience and Animations in SwiftUI app | Todo List #5
Summary
TLDR在这段视频中,Nick 带领观众构建了一个 Swift UI 待办事项应用程序,并专注于提升用户体验。当待办事项列表为空时,屏幕显得过于空白,Nick 通过添加一条消息来告知用户列表为空,并鼓励他们添加新项目。此外,他还为应用程序添加了动画效果,使界面看起来更加酷炫。Nick 展示了如何在 Xcode 中创建一个新的 SwiftUI 视图,称为“无项目视图”,并详细说明了如何使用滚动视图、文本、导航链接和按钮来设计这个视图。他还介绍了如何利用状态变量和 `.onAppear` 修饰符来实现动画效果,包括颜色变化、按钮大小变化以及阴影效果。最后,Nick 还介绍了如何自定义应用程序的强调颜色,并将其应用到整个应用程序中,以保持界面的一致性和美观性。
Takeaways
- 📝 在Swift UI中创建一个待办事项列表应用,并关注用户体验。
- 🎨 当待办事项列表为空时,添加一个提示信息,告知用户并提供添加新项的选项。
- 🔄 通过动画效果提升应用的视觉效果,使应用看起来更加酷炫。
- 🗑️ 使用UserDefaults保存应用中的项目,并在列表为空时展示一个友好的提示。
- 📱 即使列表为空,也要保持导航标题和栏项在屏幕上显示。
- 📖 创建一个新的Swift UI视图,名为“NoItemsView”,用于展示当待办事项列表为空时的界面。
- 🔍 通过ScrollView实现内容的滚动,确保内容始终位于屏幕顶部。
- 🎭 使用ZStack和条件语句来决定是展示列表还是“NoItemsView”。
- 🔗 通过NavigationView和NavigationLink在应用内部导航。
- 🎉 添加一个引人注目的按钮,鼓励用户点击以添加待办事项。
- 🌟 使用动画和交互效果,如按钮的缩放、阴影和颜色变化,增强用户界面的动态感。
- 🖌️ 通过Assets.xcassets自定义应用的Accent Color,以符合设计主题。
Q & A
在SwiftUI中,为什么要在空的待办事项列表上添加消息?
-在SwiftUI中,当待办事项列表为空时,添加消息可以提供更好的用户体验。它告知用户列表是空的,并非应用加载不完整或出现错误,同时给予用户添加新项的选项。
如何使用SwiftUI的ZStack来显示空列表消息?
-通过在ZStack中添加条件逻辑,如果`listViewModel.items`数组为空,则显示一个文本视图,上面写着“没有项目”,否则显示已剪切的列表。
在SwiftUI中,如何创建一个当待办事项列表为空时显示的自定义视图?
-创建一个新的SwiftUI视图文件,命名为`noItemsView`。在这个视图中,使用ScrollView和VStack来布局标题、描述文本和一个按钮,并通过设置字体、颜色和对齐方式来美化这个视图。
如何让待办事项列表在没有项目时显示一个提示信息,并添加一些动画效果?
-使用`@State`变量`animate`来控制动画的显示,并在`onAppear`修饰符中调用`addAnimation`函数,该函数使用`withAnimation`来改变`animate`变量的值,并添加延迟和动画效果。
在SwiftUI中,如何实现按钮的动画效果,使其看起来像是在弹跳?
-通过在`NavigationLink`上使用`.padding()`、`.scaleEffect()`和`.offset()`修饰符,以及在`.shadow()`中设置动画,可以使按钮在用户交互时产生弹跳和阴影变化的效果。
如何改变SwiftUI应用中的全局强调颜色(Accent Color)?
-在Xcode的Assets文件夹中找到并选择Accent Color,然后使用颜色面板来自定义颜色。此外,可以创建一个新的颜色集,比如命名为Secondary Accent Color,并在需要的地方使用这个新颜色。
在SwiftUI中,如何将自定义视图嵌入到应用的其他部分?
-在需要显示该视图的地方,比如`ListView`中,使用条件语句来决定是显示待办事项列表还是显示自定义的`NoItemsView`。
为什么需要在显示空列表消息时保持导航标题和栏项在屏幕上?
-保持导航标题和栏项在屏幕上有助于维持应用的导航结构和用户对应用布局的预期,即使在没有数据展示的情况下也能让用户了解他们当前在应用中的位置。
在SwiftUI中,如何避免动画效果重复执行?
-通过在执行动画代码之前添加一个检查,确保`animate`变量为`false`。如果`animate`为`true`,则不执行动画代码,这样可以避免在用户返回到该视图时动画重复执行。
在SwiftUI中,如何为新创建的空列表视图添加导航链接按钮?
-使用`NavigationLink`组件,并设置其`destination`为待添加项的视图(如`AddView`),同时为按钮设置一个吸引人的标签和可能的emoji符号,以鼓励用户进行交互。
如何让SwiftUI中的列表在删除所有项后显示自定义的空列表视图?
-在列表视图的代码中,使用一个条件语句检查列表是否有项。如果没有项,则展示`NoItemsView`视图;如果有项,则展示列表本身。
在SwiftUI中,如何为视图添加淡入效果的过渡动画?
-在视图的声明中使用`.transition(.opacity)`修饰符,并为其设置动画效果,如`.animation(.easeIn)`,以实现淡入效果的过渡动画。
Outlines
🎨 提升用户体验:为空白待办事项列表添加提示信息
Nick在视频中介绍了如何改善待办事项应用的用户体验。当待办事项列表为空时,界面看起来非常空白,这可能会让用户误以为应用没有正确加载。为了解决这个问题,他提出在屏幕上添加一条消息,告知用户列表为空,并提供一个添加新项目的选项。此外,他还计划添加一些动画效果,使应用看起来更加酷炫。
📝 创建无项目视图:引导用户添加任务
为了在待办事项列表为空时给用户更好的指引,Nick创建了一个名为'no items view'的新视图。这个视图包括一个滚动视图、一个标题和一个描述,鼓励用户点击添加按钮来添加任务。此外,还有一个导航链接按钮,使用户能够方便地跳转到添加任务的界面。
🔄 添加动画效果:提升应用互动性
为了让应用看起来更加生动,Nick在'no items view'中添加了动画效果。他首先创建了一个状态变量'animate',并在视图出现的'onAppear'事件中设置了延迟和动画逻辑。动画包括改变按钮背景颜色、按钮大小、阴影以及按钮的上下移动,以模拟按钮的悬浮效果。
🖌️ 自定义颜色:设置应用的主题颜色
Nick展示了如何自定义应用的颜色主题。他通过Xcode的资产编辑器更改了应用的强调颜色(accent color)为深紫色,并创建了一个新的颜色集作为次要强调颜色(secondary accent color),用于按钮动画的颜色变化。
📱 集成无项目视图:完成应用功能
最后,Nick将新创建的'no items view'集成到了应用的其余部分。他确保当列表为空时,展示这个新视图,并添加了透明度渐变的过渡效果,使得视图在出现时有一个平滑的动画过渡。通过在模拟器上测试,确认了动画效果和导航功能按预期工作。
Mindmap
Keywords
💡Swift UI
💡用户体验 (User Experience)
💡UserDefaults
💡Z-Stack
💡NavigationView
💡V-Stack
💡Navigation Link
💡动画 (Animation)
💡状态变量 (State Variable)
💡Accent Color
💡Transition
Highlights
在Swift UI中创建待办事项列表应用,专注于提升用户体验。
当待办事项列表为空时,屏幕上显示空白,给用户不佳的体验。
通过添加消息提示用户列表为空,并提供添加新项的选项。
为提升视觉效果,添加了动画效果。
使用UserDefaults保存应用中的项目。
在Xcode中,通过条件逻辑判断列表是否为空来展示不同的视图。
创建一个简单的视图,当待办事项列表为空时显示。
即使列表为空,也保持导航标题和栏项在屏幕上显示。
使用ZStack来根据列表是否为空显示不同的视图。
创建了一个新的Swift UI视图文件,命名为NoItemsView。
在NoItemsView中添加了滚动视图和VStack来布局文本和按钮。
为NoItemsView添加了导航标题和按钮,鼓励用户添加新事项。
使用了NavigationLink来实现在点击按钮时导航到添加视图。
为按钮添加了动画效果,包括颜色变化、缩放和阴影变化。
通过修改Assets.xcassets中的AccentColor来自定义应用的颜色主题。
创建了次要强调颜色(Secondary Accent Color)用于动画效果。
将NoItemsView整合到应用中,并在列表为空时显示。
为NoItemsView添加了透明度动画,使其平滑地出现在屏幕上。
Transcripts
[Music]
what's up everyone
i'm nick this is swiffle thinking and in
this playlist we are building a swift ui
to-do list
app and in this video we're going to
focus a little bit on
user experience because right now when
our list is
empty the screen looks really really
blank
and that's not a good user experience so
instead we're going to add a little
message on the screen
telling our users that there are no
items on the list giving them an option
to add new items and we're going to add
a little bit of animation
just to make it look really really cool
all right so we are back in xcode of
course
and in the last video in the series we
actually put together
some logic to save the items in our app
so now all of our items are being saved
in user defaults
but you might have noticed in the last
video when we first
ran our app while it was using the user
defaults
at the at the launch of the app we had
no items in our list
and it looked a little bit like this if
i delete these items
our list is completely empty so it's
correct to not show any items
but if this was an app and we had like a
user using our app
they might see this screen and think
that it didn't finish loading
because it looks very blank here we're
not really sure if
the app is just not working correctly or
is our list
actually empty so what i want to do is
put a little notification
a little text here just saying that the
to-do list is
empty just to signal to the user that
this is the list this is the screen
but there are no items right now so
we're just going to create a very simple
view to put right here when the to-do
list is empty
so we're not going to need the simulator
so i'm going to just press stop
and close out of the simulator because
the simulator does slow down your
computer a little bit it does cause the
fan to go on because it's
a lot of computing power so i try to
close it whenever possible
and in our project here i'm going to
open up
the canvas
and if you click resume on the canvas it
should build
with an empty list and that's because
we're using our new
list view model and in the preview we
don't have anything saved in the user
defaults
and what i want to do is add some logic
so that
if this list if there are no items in
this list
we show that the new view that we're
about to create instead of
this list but regardless of whether we
show a list or this new view
i want to always keep this navigation
title and the bar items on the screen
so even if we don't have this list i
still want to keep this
and what i'm going to do is add a
z-stack first
open the brackets i'm going to cut the
list in the list style
and in this z stack we're going to add
some logic we're going to say if
list view model dot
items which is the items array dot is
empty
so if it is empty and there are no items
open the brackets
and here we're going to add a text and
we'll just write
no items and then we'll say
else so if it is not empty and there is
items we're going to paste in the list
that we just cut
here so the list is only going to be
shown if there are items and then if
there are no items right now we're just
going to show this
text but regardless of whether we're
showing this text
or the list this navigation title and
the bar items will always be on the
screen
so now that we have this we can see the
no items is showing but of course
we want to customize this to make it
look better than just saying no items
so let's create a new file to do this
i'm going to open up the navigator
i'm going to right click somewhere in
the views folder create a new file
it's going to be a swift ui view and
let's call this
no items view
go ahead and click create once you're
inside click resume on the canvas
and i'm going to hide the navigator
because we're not going to use it for a
while
all right now this view is going to be
fairly simple we're going to get started
by adding a scroll view
to the screen open the brackets and if
we add some text in here we can see that
it goes all the way to the top of the
screen and part of the reason i'm adding
the scroll view if we click on it you
can see that it does
have a max height of infinity it extends
as big as possible
and also it formats the content to be
all the way at the top
and it's just handy because if we just
had text here it would be right in the
center of the screen
and i want this content to be pushed to
the top so i'm going to do a scroll view
and while we're here
let's just make it as big as possible
just in case
just in case our content isn't for some
reason the full width of the screen
so on the scroll view we'll just add dot
frame
i'm going to use the min max completion
and we only need the max width
of infinity and the max height
of infinity and you could have typed
that in directly we don't need the
alignment
you could have typed this in uh
sometimes i just like using the
completions
and one other thing i want to note is
that when we are showing this no items
view
so when we're in this list view we have
the no items here
uh we are in a navigation view so we
have a navigation title on this screen
so if i go back into our no items view
we
we are actually going to be in a
navigation view so let's add that quick
to the preview we'll add a navigation
view open the brackets
paste this inside and let's just add a
navigation title
just say title for now and just so we
know what it looks like when it's going
to be on the actual screen so our scroll
view starts down here now
and in the scroll view let's add a v
stack open the brackets
let's add a text this will be the title
that says uh there are
no items you can put whatever you want
in this title
let's make it dot font of title let's
give it a font
weight of semi-bold semi-bold always
looks good
below this text let's add a description
we'll do another text
and we're going to say are you a
productive person
i think you should click the add
button and add a bunch of items
to your to-do list and on the
entire v stack let's give it a dot
multi-line text alignment of center so
it's center aligned and
on this v stack let's add maybe some
spacing
of 10 and on the entire
v stack right below this multi-line
alignment let's just add some padding
to push it all in of maybe 40.
i think that looks good so we have our
screen mostly complete
and now all i want to do is put a button
below this so in addition to the add
button that we have on the top right of
the screen
i also want to add a big button here to
get people to actually click on it to go
to our ad view
so when we click this this button is
actually going to be a navigation
link because we want to navigate within
our navigation view we're going to push
to the add view so we'll add a
navigation
link open the parentheses we're going to
use the destination and
label completion destination will be our
ad view which we made a couple videos
back
and our label instead of just saying
navigate
let's click resume so that we know we
that it builds
our label instead of saying navigate
let's say add something
and then i'm going to press ctrl command
space to bring up the
emoji keyboard and maybe use the party
face because everybody loves the party
face
let's give this some formatting so let's
do maybe
dot foreground color of white
dot font of headline
let's give it a background color of
color dot accent
color and we're gonna update this accent
color in a second by default it is blue
that's the blue that you see like across
the whole app when we create buttons
we're going to update it in a second
actually
but before this background let's add a
dot frame
with a height of 55 and a dot frame with
a max width
of infinity after the background let's
add a dot corner radius of 10
now our button looks pretty good now we
could just leave this this looks pretty
good
but i want to add a little bit of
animation just because animations always
make
your app look a little bit better and it
would be good practice to just
run through some basic animations so at
the top of this view
let's create an at state var let's call
it animate
of type bool and we'll set it equal to
false
we want to animate when this appears on
the screen so at the bottom of the
v stack maybe underneath the padding
here let's add
on up here open the brackets
and in this on appear call we're going
to add some animation
so there's going to be a little bit of
logic in our animation call so i'm going
to actually create a
function down here underneath the body
so you can
double click on the open brackets in the
body you'll find the end of it
and underneath the body we're gonna add
a funk
add animation open and close the
parentheses
open the brackets and we're going to
call this from
our on appear call and i actually want
to use the perform completion
i clicked the wrong one before let's uh
call dot on appear
and go to the perform completion and
then we're going to get
rid of these brackets here and the
function we're going to call
is add animation let's get rid of this
one here
so ever nice and clean on up here it's
calling add animation
and this is our function and when the
screen appears
i want to delay one second before the
animation starts
so let's add a delay first we'll call
dispatch q
dot main dot async after
the deadline will be dot now plus
let's do 1.5 for 1.5 seconds
then in the execute i'm going to hit
enter and we can put our animation code
here so to cause the animation we are
going to of course
toggle the animate boolean and we want
to do it with animation so we'll call
with animation
dot ease in out which is a nice one
then we'll open the brackets and in here
we'll call animate
dot toggle so
when this appears it's going to add
animation and the add animation is going
to wait 1.5 seconds and then
toggle one thing i want to note quickly
is that
the on appear gets called every time the
screen appears
so in our app if a user had opened open
our main screen of our app
press the add button to go to the second
screen and then press the back button to
go back to this screen
the on appear would get called when they
first loaded the app
and then again when they press the back
button to come back to this screen
because the on appear gets called every
time this screen appears
and while that's good i don't want to
add the animation twice
because if we already have the animation
running we don't want to toggle it again
so just in case that ever were to happen
we're going to add a quick little check
here we're going to make sure
that this animate boolean is false
because if it's true then it's already
animating so before we call the dispatch
queue let's just call
guard not animate else
return so we're gonna say guard make
sure
animate is not true so animate is false
otherwise return because if animate is
true we're just going to return out of
the function and we're not going to go
through with this
so we're making sure we don't call it
twice and now let's add a little bit of
animation
so the first thing we're going to do is
the background and i'm going to
close the navigator and maybe zoom out a
little bit
just so we can put more code on the
screen
the background color right now is
color.accent color but let's make it
uh if it's animate we're gonna use a
ternary operator question mark
and we'll do color dot red otherwise
let's do color dot accent color
so if i click resume on the canvas and i
press the play in the live preview
it should now animate from blue to red
awesome and that was good but we can do
a little bit better i don't want to just
go from blue to red i wanted to keep
going from blue to red
so let's customize the animation so
instead of just ease in
out i'm going to delete this and i'm
going to press
enter make these on separate lines and
let's add a custom animation we'll call
animation capital a no add modifiers to
the animation we'll call dot
ease in out but this time let's use the
duration so we can make it a little bit
longer than it normally is so we'll call
2.0 for two seconds
and then we'll call dot repeat forever
and now if we click play on the live
preview it should
go from blue to red with a duration of
two seconds and it should repeat forever
and this is looking a little better
already but i think we can make it even
better
so on this navigation link on the whole
navigation link let's add some padding
let's use the edges and we'll do dot
horizontal
and then maybe let's see what it looks
like with 30.
so it's a little looks a little smaller
when it's 30 here and what about 50
and that's even smaller so let's animate
between those two we'll call
animate question mark
if it's animate we'll do 30 otherwise
50.
and now our button looks like it's kind
of getting bigger and smaller
or a little bit wider just because we're
animating the padding on the outside of
the button let's also give it a little
bit of a scale effect we'll call dot
scale effect
go down to the cg float option and we'll
do animate
if it's animate let's do 1.1 times the
the current size
otherwise we'll do 1.0 so just the
current size
so now it should get looks like it gets
a little bit bigger
and then a little bit smaller let's also
animate the offset so it looks like it's
moving up and down a little so we'll do
dot offset
and we're not going to use the x so
we'll delete it the y will do animate
question mark uh maybe negative seven
otherwise zero so it should look like
it's moving up and down now
moves up a little moves down a little
bit and
now it's moving up let's put a little
extra spacing between these two items
so underneath the text here i'm going to
call dot padding
edges of bottom and then maybe 20.
it should move it down a little
and finally let's add a little bit of
shadow onto this i think the shadow will
make it really cool and let's animate
the shadow as well
so after the padding we'll call dot
shadow
and we're going to use the color and
radius completion
and let's put all of these all these
parameters on separate lines
and my computer sounds like it is going
to overheat the fan is going crazy so
i think it's because that animation was
running but uh i'm gonna take a break
real quick so you don't have to listen
to this fan and
be right back all right so
let's animate the color of the shadow
the same way we're animating this color
here so i'm just gonna copy this
and let's put it on the shadow but
instead of the full color let's call dot
opacity of 0.7 on both of these
call it after the accent color as well
just because the shadow usually
shouldn't be as strong as the actual
the actual button color uh for the
radius let's animate it so we'll call
animate
question mark and we'll make it fairly
big when it's animating so
30 otherwise 10.
and we should see the shadow behind the
button a little bit now
uh let's keep the x as zero and
the y let's also animate so i want to
push it down a little bit so it's below
the button
because our button is hovering upward so
we'll do animate
question mark uh maybe 50 otherwise
30. so this is kind of the same amount
as
it's kind of the opposite of the padding
so our
our shadow is below it now and i think
this is going to look really cool if we
press
play so let's hit play on the live
preview and now we have our button
and it should look like it's kind of
hovering a little bit which is cool and
the shadow is animating
with the button which looks really
natural
i like it all right and now the last
thing i want to do in this video is just
update these colors because
this blue is the accent color and the
accent color
and when we've been coding all of our
buttons that default to blue
that's all because the accent color is
by default blue
but we can customize this accent color a
little bit
and i also want to change out this red
color because i want this to be a custom
color as well
so we're going to create an accent color
as well as a secondary accent color that
we're going to put
here to update the accent color globally
across our entire app
we can open up the navigator go to the
assets folder and there is a
accent color that's already in the
folder
and by default it is blue but we can
click it
here and then customize it by opening up
the inspector
we can then click on show color panel
and here we can change the color to
whatever we want
i'm on the crayons tab and i'm going to
use this dark purple here
i think this is going to be a cool
purple so this is the eggplant color
i'm going to close out of this so now
our accent color instead of blue is
purple
and i'm going to right click on this
column here
create a new color set let's call it
secondary accent color
and the secondary accent color i'm going
to change the appearance to
none for now so now right now it's just
white
but let's click on it let's open the
color panel and i'm going to make this a
different button than our purple because
it's going to animate
from this purple to this new color i'm
going to pick this maroon
because this looks like it could be kind
of natural going from purple to maroon
instead of like
purple to yellow but you're welcome to
use whatever color you want here of
course
i'm going to close out of this and now
we have our secondary accent color so
let's go back into the no items view
and i'm going to hide the navigator hide
the inspector as well we don't need that
and this color red let's change out
for our new color but we're also going
to call it down here we have color red
so since we're going to call it twice
i'm going to actually make it a variable
at the top of our screen
so up underneath this animate let's call
let
secondary accent color
equals color open the parentheses we're
gonna use the name
and it's going to be secondary accent
color
this is the name we just gave it in the
assets.xc assets folder
and let's take this secondary accent
color and where we have color red
we'll use that and down here as well
color red instead we'll call secondary
color
secondary accent color.opacity if i
click resume on the
canvas we should now see our colors
build in if it's not building click
command
shift k to clean and rebuild and then
the new color should come in so the
accent color is purple
and when we animate we should animate
from this purple to that maroon
and this is looking pretty cool all
right and the last thing we're going to
do now
is put the no items view into the rest
of our app so let's open the navigator
let's open up the list view and where we
have
no items instead we're going to add our
no items view open and close the
parentheses
so let's click run on the simulator and
test it out and see if it all looks good
all right so 1.5 seconds in we have our
animation
starting uh and if we click on this we
should navigate to the next screen
awesome and when we come back the
animation should still be going
which it looks like it is let's try one
more time we'll go add and we'll go back
and this is looking great and if we add
an item it should then go away
so i'll say my first item
save and now we have this screen of
course
we can toggle it we can then delete it
and when we delete it
our note items should be back let's
finish this up by actually adding a
little bit of transition there so that
it didn't just pop on the screen it
actually kind of animated onto the
screen
so let's take this new items view let's
call
dot transition and we'll call any
transition
dot opacity dot
animation dot ease in
so this should give a little bit of
animation when this comes onto the
screen
let's click run on the simulator one
final time
and our animation should start and let's
add an item
and that's working and then when we
delete it our new screen should kind of
animate the opacity when it comes onto
the screen
and it did that looks really cool all
right everyone
thank you all for watching that's it for
this video we are very close to being
done with his app
i hope you guys are liking it it's
looking really cool as always
i'm nick and this is swiffle thinking
and i'll see you in the next video
[Music]
you
Ver más vídeos relacionados
![](https://i.ytimg.com/vi/EPdivac0kwE/hq720.jpg)
Create a List of Todo items in SwiftUI | Todo List #1
![](https://i.ytimg.com/vi/3CasiUiJPVo/hq720.jpg)
Adding an App Icon and Launch Screen to SwiftUI | Todo List #7
![](https://i.ytimg.com/vi/SMt4_WUdKag/hq720.jpg)
Create a custom data model for Todo items in SwiftUI | Todo List #2
![](https://i.ytimg.com/vi/nwpmWu1SP1k/hq720.jpg)
Add a ViewModel with @EnvironmentObject in SwiftUI | Todo List #3
![](https://i.ytimg.com/vi/1QOLiELlpGk/hq720.jpg)
Save and persist data with UserDefaults | Todo List #4
![](https://i.ytimg.com/vi/9QciOgymGso/hq720.jpg)
macOS Menu Bar App (Code Along) | SwiftUI, Xcode
5.0 / 5 (0 votes)