1.7 创建动画效果
除了为应用程序添加音效,为项目创建平滑的动画效果也是一件非常酷的事情,因为用户会无意识地去注意一切界面中会动的部分。
在SwiftUI中创建动画的方式与其他语言稍有不同,我们并不能用简单的线性思维方式去设置视图中的动画,比如直接对某个视图执行某种方式的动画效果。一般来说,我们需要先设置一个私有布尔型变量作为标记。当特定事件发生需要产生动画效果时,就改变变量的值。而SwiftUI一旦知道变量值发生变化,就会更新屏幕上与之相关的视图,动画效果也就产生了。
可能上面的这段话会让你产生疑惑,但是不用担心,随着不断地深入学习,我们会在编写代码的过程中领会SwiftUI动画的精妙之处。
1.7.1 为卡片人物创建淡入动画
回到CardView文件,在Properties部分添加一个新的属性。
正如刚才所说,属性fadeIn用于标记一个淡入动画,初始值为false,一旦它的值为true,就会产生动画效果。
这里使用@State关键字对fadeIn变量进行封装,那@State有什么作用呢?简单来说,在程序代码中,一旦你修改了被@State封装的变量的值,与其相关的界面就会被同步修改。这是现代界面语言都支持的一种特性。
接下来,我们为Body部分的ZStack容器添加一个新的修饰器onAppear,并修改Body部分Image的代码。
对于有过swift开发经验的人来说,onAppear就相当于UIKit框架中的viewDidAppear()方法,当视图出现在屏幕上的时候,会执行其中的代码。
在onAppear()修饰器的闭包中,调用了withAnimation()方法,它会执行一个线性动画,动画时长是1.2s。那么,怎么执行这1.2s的动画呢?在withAnimation()方法的闭包中,我们改变了fadeIn变量的值,因为它是被@State封装的,所以它的值一旦发生变化,相关的视图就会产生相应的动画。
在ZStack容器中,我们让Image的透明度根据fadeIn的变化而变化。如果fadeIn为false,则人物图像隐去,如果fadeIn的值变为true,则透明度会在1.2s的时间从0.0变为1.0,从而实现淡入的效果。
在预览窗口中启动Live模式,可以查看卡片的动画效果。
1.7.2 为标题创建下滑入动画效果
有了上面一节的实践经验,我们再为标题添加下滑入的动画效果。同样是在Properties部分添加一个被@State封装的私有布尔型变量。
moveDownward变量相当于标题下滑动画的启动器,一旦卡片视图出现就产生一个0.8s的线性动画,这里让负责组织标题的VStack容器从y方向-300点的位置下滑到-218点。
在预览窗口中启动Live模式,可以查看卡片中标题的动画效果。
1.7.3 为按钮创建上滑入动画效果
在本节的最后,我们为卡片中的按钮添加上滑入动画效果。依然是在Properties部分添加一个被@State封装的私有布尔型变量。
因为是与标题下滑入相同时长的线性动画,所以在onAppear修饰器中的第2个withAnimation中添加了对moveUpward的设置。一旦该值发生变化,就让Button从y方向300点的位置上滑到210点。
目前,针对卡片的3个动画效果已经全部完成,可以在Xcode顶部的活动方案(Set the active scheme)列表中选择iPad设备进行测试,这里选择iPad Pro(9.7-inch),然后在模拟器中运行,效果如图1-29所示。
图1-29 在iPad模拟器中测试项目的运行效果