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

SwiftUI 新特性:Animatable 宏的使用与原理解析

网罗开发 (小红书、快手、视频号同名)

  大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等方向。在移动端开发、鸿蒙开发、物联网、嵌入式、云原生、开源等领域有深厚造诣。

图书作者:《ESP32-C3 物联网工程开发实战》
图书作者:《SwiftUI 入门,进阶与实战》
超级个体:COC上海社区主理人
特约讲师:大学讲师,谷歌亚马逊分享嘉宾
科技博主:华为HDE/HDG

我的博客内容涵盖广泛,主要分享技术教程、Bug解决方案、开发工具使用、前沿科技资讯、产品评测与使用体验。我特别关注云服务产品评测、AI 产品对比、开发板性能测试以及技术报告,同时也会提供产品优缺点分析、横向对比,并分享技术沙龙与行业大会的参会体验。我的目标是为读者提供有深度、有实用价值的技术洞察与分析。

展菲:您的前沿技术领航员
👋 大家好,我是展菲!
📱 全网搜索“展菲”,即可纵览我在各大平台的知识足迹。
📣 公众号“Swift社区”,每周定时推送干货满满的技术长文,从新兴框架的剖析到运维实战的复盘,助您技术进阶之路畅通无阻。
💬 微信端添加好友“fzhanfei”,与我直接交流,不管是项目瓶颈的求助,还是行业趋势的探讨,随时畅所欲言。
📅 最新动态:2025 年 3 月 17 日
快来加入技术社区,一起挖掘技术的无限潜能,携手迈向数字化新征程!


文章目录

    • 前言
      • 先从一个简单的例子说起
      • 传统的做法:使用 Animatable 协议
      • 全新方案:使用 Animatable 宏
      • 完整可运行示例
      • 忽略某些属性:使用 AnimatableIgnored
      • 内部原理:宏背后做了什么?
      • 应用场景分析
      • 总结

前言

在 SwiftUI 中,实现平滑、自然的动画一直是它的强项。
不过在 WWDC 最新的更新里,Apple 又把动画的实现难度进一步降低——引入了一个全新的宏:@Animatable

这篇文章我们就来聊聊它的使用方式、背后的逻辑,以及在开发中可以带来哪些实实在在的便利。

先从一个简单的例子说起

假设我们想要在界面上显示一个整数,并在点击按钮后从 0 动画增加到 100。
我们可能会先写出这样的代码:

struct IntegerView: View {var number: Intvar body: some View {Text(number.formatted())}
}struct ContentView: View {@State private var number = 0var body: some View {VStack {IntegerView(number: number).animation(.default.speed(0.5), value: number)Button("Animate") {number = 100}}}
}

这段代码看上去没问题,但运行后你会发现一个问题:
当我们点击“Animate”按钮时,数值直接从 0 跳到了 100,并没有平滑过渡。

这是因为 SwiftUI 并不知道该如何“逐步变化”一个整数。
它只知道两个状态:“0” 和 “100”,于是只能简单地替换文字。

传统的做法:使用 Animatable 协议

早期我们要解决这个问题,需要让自定义的视图(比如 IntegerView)遵守 Animatable 协议。
这个协议会告诉 SwiftUI:哪些属性是可以被插值(interpolated)的,也就是可以被动画过渡的

例如,我们可以这样写:

struct IntegerView: View, Animatable {var number: Doublevar animatableData: Double {get { number }set { number = newValue }}var body: some View {Text(number.formatted(.number.precision(.fractionLength(0))))}
}

这样,SwiftUI 就知道如何让 number 从 0 平滑地过渡到 100。
虽然能用,但这种写法比较“手动”,尤其当视图属性多的时候,需要逐个实现 animatableData

全新方案:使用 Animatable 宏

在新的 SwiftUI 版本中,Apple 提供了更轻量的写法。
我们只需要用一个宏 @Animatable,就能让视图自动获得动画能力。

@Animatable
struct IntegerView: View {var number: Floatvar body: some View {Text(number.formatted(.number.precision(.fractionLength(0))))}
}

可以看到,我们做了两点调整:

  1. 在结构体上添加了 @Animatable
  2. number 的类型从 Int 改成了 Float

这是因为 @Animatable 只适用于遵循 VectorArithmetic 协议 的类型,而 Float 就是其中之一。

完整可运行示例

现在我们来看看完整的可运行代码:

import SwiftUI@Animatable
struct IntegerView: View {var number: Floatvar body: some View {Text(number.formatted(.number.precision(.fractionLength(0)))).font(.system(size: 48, weight: .bold)).foregroundColor(.blue).padding()}
}struct ContentView: View {@State private var number: Float = 0var body: some View {VStack(spacing: 40) {IntegerView(number: number).animation(.easeInOut(duration: 2), value: number)Button("Animate") {number = 100}.font(.title2).buttonStyle(.borderedProminent)}.padding()}
}

运行后你会发现,当点击按钮时,数字会从 0 平滑过渡到 100
整个动画自然流畅,而且代码量比原来少了很多。

SwiftUI 在内部帮我们自动完成了 Animatable 协议的实现逻辑。

忽略某些属性:使用 AnimatableIgnored

有时候我们可能不希望让某个属性参与动画,比如一些常量配置或调试参数。
这个时候就可以使用 @AnimatableIgnored 宏。

@Animatable
struct IntegerView: View {var number: Float@AnimatableIgnoredvar ignoredValue: Float = 10.0var body: some View {Text(number.formatted(.number.precision(.fractionLength(0)))).font(.system(size: 40)).foregroundColor(.purple)}
}

加上 @AnimatableIgnored 后,ignoredValue 将不会被动画系统考虑。
这非常有用,尤其在一些复杂自定义 View 中,能让你精准控制动画范围。

内部原理:宏背后做了什么?

@Animatable 的作用,其实就是帮我们自动生成了符合 Animatable 协议的代码。
如果你手动实现,它大致相当于:

struct IntegerView: View, Animatable {var number: Floatvar animatableData: Float {get { number }set { number = newValue }}var body: some View { ... }
}

当我们有多个可以插值的属性时,SwiftUI 会自动把它们组合成一个“向量”来计算变化。
因此,只要属性类型支持 VectorArithmetic,动画就能自然地工作。

应用场景分析

  1. 数字变化类 UI
    比如积分、温度、速度、进度值等动态数字展示,使用 @Animatable 能让数字从旧值平滑过渡到新值。

  2. 图表或进度条
    当数据更新时,直接用动画展示变化过程,比突兀的数值跳变更自然。

  3. 自定义形状动画
    在 Shape 或 Path 中定义参数(例如半径、角度、长度),使用 @Animatable 也能自动实现形状的平滑过渡。

总结

新的 @Animatable 宏让 SwiftUI 动画变得更轻松了:

  • 不再需要手动实现 Animatable 协议;
  • 支持自动识别并插值所有符合 VectorArithmetic 的属性;
  • 搭配 @AnimatableIgnored 可以灵活排除不需要动画的字段。

一句话总结就是:

“过去我们需要告诉 SwiftUI 哪些属性能动;现在只需要告诉它哪些不能动。”

这无疑让动画开发更加直观、优雅,也更符合 SwiftUI “声明式开发”的理念。

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

相关文章:

  • 网站制作优质公司html网站后台模板
  • 电子商务网站开发系统江西seo
  • 如何改进网站服务建设和管理安装wordpress到服务器
  • 用帝国做网站怎么样做网站必须知道的问题
  • 一场协议转换的“破壁”之旅:CC-Link IE转PROFINET网关实战手记
  • 【05】方向梯度直方图(HOG)详解:从原理到实现
  • 在淘宝做印刷网站怎么办网站主要栏目
  • 监督对齐DPO算法实例讲解
  • 建设网站应该注意些什么个人域名备案需要多久
  • C语言条件编译的应用与优化技巧 | 探讨条件编译在项目中的实际运用与优化方法
  • 网页数据抓取:融合BeautifulSoup和Scrapy的高级爬虫技术
  • LeetCode 2654. 使数组所有元素变成 1 的最少操作次数 - GCD 思维题详解
  • 站长统计芭乐官方网站下载wordpress移动主题开发教程
  • 网站开发大学是什么专业营销型企业网站系统模板下载
  • JavaScript 35个数组方法完整参数返回值表
  • PPP协议异界冒险:连接神殿的试炼
  • 网站建设的基本条件网站制作协议
  • kotlin build.gradle.kts下修改APK的输出名称
  • 帝国cms地方门户网站模板室内设计效果图素材网站
  • 淘客网站怎么建设小程序商城货源怎么找
  • 在线编译C语言:提升跨平台开发效率
  • 诊断数据库 --- ODX和PDX关系核区别
  • 阿里云申请域名后网站转运网站建设
  • 第13章 函数式语言特性
  • C语言防止反编译工具 | 提高程序安全性并保护源代码
  • 【实战】动态 SQL + 统一 Result + 登录校验:图书管理系统(下)
  • 双缓冲机制:如何避免读写冲突
  • C语言在线编译器网站 | 高效便捷的编程学习平台
  • 你的技术搭子在这里!来openFuyao社区SIG与大咖一起组队
  • 台州自助建站系统做兼职上哪个网站