当前位置: 首页 > news >正文

iOS SwiftUI 动画开发指南

iOS SwiftUI 动画开发指南

为了把大家吸引过来,先上几张动画效果图:

“引狼图”1:按钮点击 - 果冻动画效果
果冻效果
“引狼图”2:波纹动画效果
在这里插入图片描述
“引狼图”3:Lottie复杂动画效果
在这里插入图片描述

1、动画概念

SwiftUI 的动画是基于声明式的,当视图的状态发生变化时,系统会自动在旧状态和新状态之间插入中间帧,创建平滑的过渡效果。

工作原理:
状态驱动:动画由状态变化触发
声明式语法:描述"做什么"而不是"怎么做"
自动插值:系统自动计算中间值
类型安全:编译时检查动画兼容性

1.1、隐式动画

隐式动画通过 .animation() 修饰符自动应用于视图的所有可动画属性变化。当修饰符观察的值发生变化时,所有可动画的属性都会以指定的动画方式过渡。

隐式动画特点:

  • 使用 .animation() 修饰符
  • 状态变化时自动动画
  • 代码简洁,声明式
import SwiftUIstruct SimpleImplicitAnimation: View {@State private var isTapped = falsevar body: some View {VStack(spacing: 30) {// 圆形视图 - 点击后会放大并变色Circle().fill(isTapped ? .blue : .red)        // 颜色变化.frame(width: isTapped ? 150 : 100,   // 大小变化height: isTapped ? 150 : 100).animation(.easeInOut(duration: 0.5), value: isTapped) // 隐式动画Button("点击动画") {isTapped.toggle() // 状态变化自动触发动画}}}
}
1.2、显式动画

显式动画使用 withAnimation 闭包,只对闭包内的状态变化应用动画。可以精确控制哪些状态变化应该动画,以及使用什么样的动画参数。

显式动画特点:

  • 使用 withAnimation { } 闭包
  • 精确控制哪些变化有动画
  • 手动触发动画
struct SimpleExplicitAnimation: View {@State private var isTapped = falsevar body: some View {VStack(spacing: 30) {// 圆形视图Circle().fill(isTapped ? .green : .orange)    // 颜色变化.frame(width: isTapped ? 150 : 100,   // 大小变化height: isTapped ? 150 : 100)// 注意:这里没有 .animation() 修饰符Button("点击动画") {// 使用 withAnimation 显式包装状态变化withAnimation(.easeInOut(duration: 0.5)) {isTapped.toggle() // 只有这个变化有动画}}}}
}
1.3、动画曲线

在 SwiftUI 中,动画曲线(也称为时序曲线或缓动函数)定义了动画随时间变化的速度和节奏。它们让动画看起来更自然、更流畅。

1.3.1、线性动画 (Linear)

匀速动画,速度保持不变。

.animation(.linear(duration: 1.0), value: value)

1.3.2、缓动动画 (Ease)

速度会变化,提供更自然的运动效果。
包含:缓入(.easeIn)、缓出(.easeOut)、缓入缓出(.easeInOut,默认)

.animation(.easeInOut(duration: 1.0), value: value)// 开始慢 → 中间快 → 结束慢
// 最自然的运动曲线
.animation(.easeIn(duration: 1.0), value: value)// 开始慢 → 逐渐加速到结束
.animation(.easeOut(duration: 1.0), value: value)// 开始快 → 逐渐减速到结束

1.3.3、弹性动画 (Spring)

模拟弹簧物理效果,带有回弹。

.animation(.spring(response: 0.6,        // 持续时间dampingFraction: 0.8, // 阻尼(0-1,越小弹性越大)blendDuration: 0.25   // 混合持续时间),value: value
)

1.3.4、交互式弹簧 (Interpolating Spring)

更精确控制弹簧物理参数的动画。

.animation(.interpolatingSpring(mass: 1.0,        // 质量:影响惯性stiffness: 100,   // 刚度:影响回弹力度damping: 10,      // 阻尼:影响阻力initialVelocity: 0 // 初始速度),value: value
)

1.3.5、自定义动画曲线
timingCurve 是 SwiftUI 中用于创建自定义动画曲线的函数,它使用三次贝塞尔曲线来精确控制动画的加速和减速过程。

.animation(.timingCurve(0.25,   // 控制点1 X: 开始阶段的弯曲程度0.1,    // 控制点1 Y: 开始阶段的速度  0.25,   // 控制点2 X: 结束阶段的弯曲程度1.0,    // 控制点2 Y: 结束阶段的速度duration: 1.0  // 动画总时长), value: value
)
1.4、动画重复

1.4.1、使用 repeatCount 指定重复次数

struct RepeatCountExample: View {@State private var scale: CGFloat = 1.0var body: some View {Circle().fill(Color.blue).frame(width: 100, height: 100).scaleEffect(scale).onAppear {withAnimation(.easeInOut(duration: 0.5).repeatCount(3) // 重复3次) {scale = 1.5}}}
}

1.4.2、使用 repeatForever 无限重复

struct RepeatForeverExample: View {@State private var rotation: Double = 0var body: some View {Rectangle().fill(Color.red).frame(width: 100, height: 100).rotationEffect(.degrees(rotation)).onAppear {withAnimation(.linear(duration: 1.0).repeatForever(autoreverses: false) // 无限重复,不自动反向) {rotation = 360}}}
}

1.4.3、带自动反向的重复

struct AutoreverseExample: View {@State private var offsetY: CGFloat = 0var body: some View {Circle().fill(Color.green).frame(width: 80, height: 80).offset(y: offsetY).onAppear {withAnimation(.easeInOut(duration: 0.8).repeatForever(autoreverses: true) // 来回弹跳) {offsetY = 100}}}
}

2、基础动画示例

2.1、位移动画 (Move)
import SwiftUIstruct MoveAnimationSimple: View {@State private var moveRight = falsevar body: some View {VStack {Circle().fill(.blue).frame(width: 80, height: 80).offset(x: moveRight ? 100 : 0) // X轴位移.animation(.easeInOut(duration: 1.0), value: moveRight)Button("移动") {moveRight.toggle()}}}
}
2.2、旋转动画 (Rotation)
struct RotationAnimationSimple: View {@State private var rotate = falsevar body: some View {VStack {Rectangle().fill(.red).frame(width: 100, height: 100).rotationEffect(.degrees(rotate ? 180 : 0)) // 旋转角度.animation(.easeInOut(duration: 1.0), value: rotate)Button("旋转") {rotate.toggle()}}}
}
2.3、缩放动画 (Scale)
struct ScaleAnimationSimple: View {@State private var scaleUp = falsevar body: some View {VStack {Circle().fill(.green).frame(width: 80, height: 80).scaleEffect(scaleUp ? 1.5 : 1.0) // 缩放比例.animation(.easeInOut(duration: 1.0), value: scaleUp)Button("缩放") {scaleUp.toggle()}}}
}
2.4、透明度动画 (Opacity)
struct OpacityAnimationSimple: View {@State private var show = falsevar body: some View {VStack {Circle().fill(.orange).frame(width: 100, height: 100).opacity(show ? 1.0 : 0.3) // 透明度.animation(.easeInOut(duration: 1.0), value: show)Button("淡入/淡出") {show.toggle()}}}
}
2.5、颜色动画 (Color)
struct ColorAnimationSimple: View {@State private var changeColor = falsevar body: some View {VStack {Rectangle().fill(changeColor ? .purple : .blue) // 颜色变化.frame(width: 120, height: 120).animation(.easeInOut(duration: 1.0), value: changeColor)Button("变色") {changeColor.toggle()}}}
}
2.6、圆角动画 (Corner Radius)
struct CornerRadiusAnimationSimple: View {@State private var roundCorners = falsevar body: some View {VStack {Rectangle().fill(.red).frame(width: 120, height: 120).cornerRadius(roundCorners ? 60 : 0) // 圆角变化.animation(.easeInOut(duration: 1.0), value: roundCorners)Button("圆角") {roundCorners.toggle()}}}
}

3、组合动画示例

3.1、多个属性同时动画

同时为视图的多个属性应用动画

struct CombinedAnimationView: View {@State private var isAnimating = falsevar body: some View {VStack(spacing: 30) {Text("组合动画").font(.title)RoundedRectangle(cornerRadius: isAnimating ? 50 : 10).fill(isAnimating ? .blue : .red).frame(width: isAnimating ? 200 : 100,height: isAnimating ? 200 : 100).rotationEffect(.degrees(isAnimating ? 180 : 0)).opacity(isAnimating ? 0.8 : 1.0).animation(.easeInOut(duration: 1.5),value: isAnimating)Button("触发组合动画") {isAnimating.toggle()}}.padding()}
}
3.2、序列动画

使用多个 withAnimation 创建顺序执行的动画

此处模拟实现按钮点击 - 果冻动画效果:
在这里插入图片描述

struct Anim1: View {@State private var scaleX = 1.0@State private var scaleY = 1.0var body: some View {Button("button"){doAnim()}.foregroundColor(.white).padding(.horizontal, 50).padding(.vertical, 40).background(Color.blue).cornerRadius(10).scaleEffect(x:scaleX, y: scaleY)}func doAnim(){Task{@MainActor inwithAnimation(.spring(response:0.1, dampingFraction: 0.8)){scaleX = 0.8scaleY = 1.2}await try Task.sleep(for: .seconds(0.1))withAnimation(.interpolatingSpring(mass: 1.0, stiffness: 200, damping: 8)){scaleX = 1.0scaleY = 1.0}}}
}

4、Lottie动画

使用SwiftUI动画可实现基础的动画效果,如果动画包含复杂逻辑,建议使用Lottie实现(线上有很多的lottie动画文件(.json)可直接使用)
Lottie 是一个由 Airbnb 开发的开源库,用于在 iOS、Android 和 Web 上展示高质量的动画。使用 Lottie 动画能够为你的 SwiftUI 应用增添更丰富的交互和视觉效果,同时保持良好的性能和用户体验。

SwiftUI 中使用 Lottie 动画的一般步骤:
1、安装 Lottie 库:可以使用Swift Package Manager 或者 CocoaPods
2、SwiftUI 视图导入 Lottie 模块:import Lottie
3、Lottie 动画 JSON 文件添加到你的项目中
4、SwiftUI 视图中使用 LottieView加载动画文件

在这里插入图片描述
json文件管理、动画加载参考:
在这里插入图片描述
在这里插入图片描述

http://www.dtcms.com/a/568558.html

相关文章:

  • LeetCode算法学习之验证回文串
  • 深入掌握 OpenCV-Python:从图像处理到智能视觉
  • 运输层协议概述及UDP
  • 【多所高校合作】第四届图像处理、计算机视觉与机器学习国际学术会议(ICICML 2025)
  • 什么网站做h5做得好登录不上wordpress
  • 个人制作的网站模板自助建站自己要做网站的来看下
  • 第十五周Fscan和利用漏洞上线远程和数据库提权上线远控
  • 第5章 所有权系统
  • 从零开始学Flink:事件驱动
  • 机器学习实现逻辑回归-癌症分类预测
  • Kafka 从入门到精通完整指南
  • 常见二三维GIS数据分类及处理流程图
  • LLM结构化输出:约束解码、CFG和response_format
  • 做网站麻烦不文山网站建设求职简历
  • wordpress网站静态页面外国食品优秀设计网站
  • hybrid
  • C++中malloc、free和new、delete的区别
  • 计算机视觉:python车辆行人检测与跟踪系统 YOLO模型 SORT算法 PyQt5界面 目标检测+目标跟踪 深度学习 计算机✅
  • 提高肠氧饱和度测量精度的新技术评估
  • 【数据集+源码+文章】基于yolov8+streamlit的12种水果品质、成熟度检测系统
  • Camera参数(3A)
  • 【C++:搜索二叉树】二叉搜索树从理论到实战完全解读:原理、两种场景下的实现
  • 高性能网络编程实战:用Tokio构建自定义协议服务器
  • H265 vs AV1 vs H266帧内块拷贝差异
  • CSS 中 `data-status` 的使用详解
  • 舟山企业网站建设公司微信小程序麻将辅助免费
  • VMware替代 | 详解ZStack ZSphere产品化运维六大特性
  • 缓存击穿,缓存穿透,缓存雪崩的原因和解决方案(或者说使用缓存的过程中有没有遇到什么问题,怎么解决的)
  • 关于数据包分片总长度字段的计算和MF标志位的判断
  • 手机网站建站流程网站建设卩金手指科杰