Skip to main content
Language简体中文
工程5 分钟阅读2026 年 10 月

SwiftUI 中的弹簧动画如何工作?

简短回答

在 SwiftUI 中,您可以使用 .animation(.spring) 或 withAnimation(.spring) 添加弹簧。从 iOS 17 开始,主要设置是持续时间和弹跳,并且有预设:.smooth(无弹跳)、.snappy(一点)和 .bouncy(更多)。较旧的代码使用响应和阻尼分数。当新动画中断时,SwiftUI 弹簧会保持其速度,这使手势感觉很自然。

核心要点

  • 使用 withAnimation(.spring) 进行状态更改,或在视图上使用 .animation(.spring, value:)
  • iOS 17+:.spring(duration:bounce:) 加上 .smooth、.snappy 和 .bouncy 预设
  • 旧 API:.spring(response:dampingFraction:blendDuration:)
  • 自 iOS 17 起,弹簧是 SwiftUI 的默认动画样式
  • 断续弹簧保持其速度,因此手势可以顺利传递

SwiftUI 以动画形式呈现状态变化。当 isExpanded 之类的值在 withAnimation(.spring) 中发生变化时,依赖于它的每个视图都会使用 spring 移动到新的布局。

在 iOS 17 及更高版本中,描述弹簧的最简单方法是使用两个值:持续时间,即稳定所需的大致时间;以及弹跳,即超出的程度。弹跳为 0 可实现平滑运动,不会出现过冲;较高的值会增加弹跳力。 Apple 还提供预设:.smooth、.snappy 和 .bouncy。

较旧的代码使用 .spring(response:dampingFraction:)。响应与持续时间类似,阻尼分数为 1 意味着没有反弹,而较低的值会增加反弹。两种形式都描述了相同的物理弹簧。

弹簧的一大优点是中断。如果用户再次点击或拖动手势在动画中结束,新的弹簧将从当前位置和速度开始,因此不会发生跳跃。对于拖动手势,当用户释放时传递手势的速度,以便元素继续沿其抛出的方向移动。

如果同一组件还需要在 Web 或 Android 上运行,则将弹簧值保留为共享运动令牌会有所帮助。我们制作的 ExodeUI 具有 SwiftUI 运行时,因此带有弹簧的设计组件可以在 SwiftUI 和其他平台上运行。

常见问题

SwiftUI中的默认动画是什么?

从 iOS 17 开始,默认动画是平滑的弹簧。

.snappy 和 .bouncy 有什么区别?

.snappy 很快就稳定下来,并有一个小超调; .bouncy 超调更多。 .smooth 没有超调。

如何将响应和阻尼分数转换为持续时间和弹跳?

响应大致映射到持续时间。阻尼分数为 1 时弹跳为 0;较低的阻尼分数意味着更多的弹跳。

如何通过拖动手势添加速度?

当拖动结束时读取速度并使用插值弹簧或接受初始速度的较新弹簧 API。

相关指南和示例

在编写代码之前调整弹簧

拖动滑块,观察运动,并复制 SwiftUI、CSS 和其他平台的弹簧值。

打开弹簧发生器
ExodeUI

EXODEUI DESKTOP

A little space for good ideas.

Choose your platform to get the official ExodeUI installer.

Looking for Intel Mac or other builds? Explore the web studio or check all download options.

Prefer the browser? Try for free in your browser →