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 种类(还有比如spring、interactiveSpring、timingCurve等用法后面会讲到,目前为止,了解这 4 种足够一般情况下的使用了)。

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

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

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

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

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

例如:

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

插值动画

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

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

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

相关推荐
黑化旺仔1 天前
【OC】Runtime:类元数据、加载初始化与消息派发
开发语言·macos·ios·objective-c
songgeb1 天前
iOS App支持设置RTL语言的实践
ios·swift·ui kit
软泡芙1 天前
【iOS】swift启动屏显示黑屏
ios
用户69371750013841 天前
当你向领导申请 AI 编程工具预算时,如果领导追问“能提效多少,有量化数据吗”,你该怎么回答?
android·后端·ios
Layer1 天前
一些脱离 Mac 依赖的 Agent 操作 iPhone 实现
ios·ai编程·测试
用户69371750013841 天前
当我说 Claude 搭配 GLM-5.3-Flash 太好用了,同事却提醒我:你可能正在失去对代码的掌控
android·后端·ios
茶底世界之下1 天前
一键裁方会丢掉什么?用 Awaking 给园林照片做两种画幅
ios
Marco_Marco1351 天前
定位SDK接入实战:Android/iOS/鸿蒙三端怎么选、怎么接
android·ios·harmonyos
老李IT笔记2 天前
关掉设备上的 AI 扩展:两个键各管一层,配错了等于没配
人工智能·ios·智能手机
2501_915921432 天前
iOS应用耗电测试:使用Energy Log、Keymob和Instruments进行性能监控与能源消耗分析
android·ios·小程序·https·uni-app·iphone·webview