QuickStart:快速上手SwiftUI动画

动画的英文有很多表述,如 Animation、Cartoon、Animated等。其中较正式的 「Animation」 一词源自于拉丁文字根 anima,意思为「灵魂」,动词 Animate 是「赋予生命」的意思,引申为使某物活起来的意思。所以动画可以定义为使用绘画的手法,创造生命运动的艺术。

在 SwiftUI 中,动画的实现非常简洁而强大,它提供了一系列内置的动画类型和方法,让我们通过少量代码就能创建出引人注目的动画效果。不过在深入讲解 「SwiftUI 动画」之前,我们先探索下怎么产生的动画?

产生动画的步骤

大多数动画的创作流程可概括为三个核心步骤:

  1. 启动:定义一个「初始状态」,即动画开始之前的布局和外观。
  2. 变化:指的是动画「动起来的过程」,这一阶段中属性(如位置、大小、颜色等)发生变化,形成动画效果。
  3. 终止:确定「最终状态」,动画完成后视图应达到的布局和外观。

动画启动的时机

动画启动需要依赖于某种触发因素。所谓「触发因素」,指的是那些能够激发或引发动画开始的事件或动作。这种触发可以是按下一个按钮、某个值的改变,或者是如屏幕显示这样的特定事件。

如上图所示,当「点击」按钮后,圆圈「由上到下」移动了位置。 此时,满足了动画产生的所有条件:有「启动-变化-终止」的变化过程,也有「触发因素」,现在看下在 SwiftUI 中的实现:

swift 复制代码
HStack {
	Button("按钮") {
		changed.toggle()
	}.buttonStyle(.borderedProminent)
		.controlSize(.large)
	Spacer()
	Circle().fill(.blue)
		.frame(width: 100)
		.offset(y: changed ? 200 : 0)
}.padding()
  1. 按钮点击触发了change「值」的改变(false -> true)。
  2. change值的改变又使得小球的「偏移量」在y轴产生了改变(0 -> 200)

问题来了,为什么没有看到「动画效果」?

SwiftUI 实现动画效果

实现起来非常简单,只需为小球Circle()增加一个.animate()修饰符。

swift 复制代码
Circle().fill(.blue)
		.frame(width: 100)
		.offset(y: changed ? 200 : 0)
		.animation(.easeIn, value: changed)

如下图所示,此时小球移动过程中产生了动画的渐进效果:

看下.animate()修饰符的文档:

从文档中的释义我们能得出几个结论:

  1. to this view:意味着修饰的是视图,所以无论是文本(Text)、图片(Image)或容器视图(HStack、VStack、List等),只要是视图,都可用动画修饰符,区别是修饰文本、图片影响到的是「视图本身」,而修饰容器视图还会影响到它的「子视图」。
  2. the specified value changed:SwiftUI 之所以能识别哪里应该产生动画,就是通过监控value值的变化来实现的,所以控制值、改变值是产生动画的必要条件。它相当于用来定义动画产生的「启动」和「终止」。
  3. Applies the given animation:这句话描述的就是「变化」的过程,通过修改第一个参数_ animation: Animation, 可以定制不同的变化效果。

动画曲线

「动画曲线」(变化效果)是表达整个动画持续时间内速度的一种方式。在前面的例子中,看到了easeIn的用法。以图形方式表达如下: 开始启动的时候变化「较慢」,后面变化的速度会逐渐「加快」。所以对应上例中的小球移动来说,小球「启动」的移速会较慢,随着时间的流逝,「速度」会逐渐加快,直到「终止」。 下面是 4 种常用的 Animation 种类(还有比如springinteractiveSpringtimingCurve等用法后面会讲到,目前为止,了解这 4 种足够一般情况下的使用了)。

让我们通过一个具体的 SwiftUI 示例,来具体了解下这四种动画曲线的区别:

尽管都设置了「同样」( 2 秒)的动画执行「时间间隔」,但是不同的动画曲线使得它们执行的或「快」或「慢」,肉眼可见的看到差别。

上例中,均使用了改变视图的偏移量(Offset)产生移动视图的动画,除此之外,还有其它的属性能够产生动画吗?

后续的章节中,会陆续列举各种各样的案例来产生动画。所以到目前为止,我们只需要知道一点:

大多数「数值型」的属性都可以用来动画化

例如:

视图的偏移量(改变位置)、视图的高与宽(改变尺寸)甚至包括视图的颜色等,用数值来"表达"(可计算)的属性大多数(不是全部)都能用来产生「动画」。

插值动画

SwiftUI 构建在响应式编程的概念之上,其中视图的显示和行为是由「数据状态」决定的。当这些数据状态发生「变化」时,SwiftUI 自动「重新计算」视图(重新渲染),确保用户界面与数据状态保持一致。

当一个「可动画化」的属性改变时,SwiftUI 不仅仅是简单地重新计算视图。而是使用了「插值」(interpolation)技术在旧值和新值之间计算出「中间值」。这个过程会在一段时间内持续进行,形成了一个平滑的动画效果。

如上例中的小球移动,它的偏移量从 0 逐渐增长到 200,SwiftUI 将计算出 0 到 200 之间的所有中间值,并逐渐应用这些值,从而产生移动的效果。

相关推荐
m0_748238921 小时前
webgis入门实战案例——智慧校园
开发语言·ios·swift
Legendary_0085 小时前
LDR6020在iPad一体式键盘的创新应用
ios·计算机外设·ipad
/**书香门第*/14 小时前
Laya ios接入goole广告,搭建环境 1
ios
wakangda20 小时前
React Native 集成 iOS 原生功能
react native·ios·cocoa
Swift社区1 天前
Excel 列名称转换问题 Swift 解答
开发语言·excel·swift
crasowas2 天前
iOS - 超好用的隐私清单修复脚本(持续更新)
ios·app store
ii_best2 天前
ios按键精灵脚本开发:ios悬浮窗命令
ios
Code&Ocean2 天前
iOS从Matter的设备认证证书中获取VID和PID
ios·matter·chip
/**书香门第*/2 天前
Laya ios接入goole广告,开始接入 2
ios
东坡肘子2 天前
肘子的 Swift 周报 #063|异种肾脏移植取得突破
swiftui·swift·apple