白玉微瑕:闲谈 SwiftUI 过渡(Transition)动画的“口是心非”(下)
概述
秃头小码农们都知道,SwiftUI 不仅仅是一个静态 UI 构建框架那么简单,辅以海量默认或自定义的动画和过渡(Transition)特效,我们可以将 App 界面的绚丽升华到极致。
不过,目前 SwiftUI 中的过渡(Transition)动画在某些“敏感”场景中会有让人意想不到的效果,我们如何随机应变回归本源呢?本篇由此应运而生。
在本篇博文中,您将学到如下内容:
- 概述
- 3. Transition 动画之“怪癖”
- 4. 暗度陈仓:用动画(Animation)代替过渡(Transition)
- 总结
本文示例代码测试环境:macOS 15.2 + Xcode 16.1
百闻不如一见,那小伙伴们还等什么呢?让我们马上开始 Transition 动画除虫大冒险吧!
Let‘s go!!😉
3. Transition 动画之“怪癖”
虽然 Transition 动画在大多数情况下表现的都十分惊艳,但“金无足赤,人无完人”,Transition 动画在某些场景下也会“选择性失灵”。
其中一种场景就是:若视图同时包裹在 NavigationStack 和 Form(或 List)容器内,则视图的插入 Transition 过渡动画会消失不见,变为“鸟迹虫丝”。
在下面的代码中,我们测试的两枚绿色圆形分别放在了不同的容器中:
- 顶部的圆形放在 NavigationStack 和 List 中;
- 底部的圆形只放在了 NavigationStack 中;
struct ContentView: View {@State var magic = falsevar body: some View {NavigationStack {VStack(alignment: .leading) {List {Section("同时嵌入在 NavigationStack 或 List 中") {VStack {if magic {Circle().foregroundStyle(.green).frame(width: 100, height: 100).transition(.scale)}Spacer()Text("没有插入,只有消失时的缩放过渡动画")}.frame(height: 200)}}.listStyle(.plain)Divider()Section("只嵌入在 NavigationStack 中") {VStack {if magic {Circle().foregroundStyle(.green).frame(width: 100, height: 100).transition(.scale)}Spacer()Text("插入和消失时皆有缩放过渡动画")}.frame(height: 200)}Button("Magic") {withAnimation(.bouncy) {magic.toggle()}}}.padding().navigationTitle("过渡动画“怪癖”演示")}}
}
运行结果如下所示:
可以看到:顶部圆形没有插入过渡动画,而底部圆形的过渡动画完美无缺。
注意,上面代码中两个圆形视图上的过渡动画代码都是完全一致的,不存在特殊对待的情况。
若想进一步了解 SwiftUI 中动画的各种高级操作技能,请小伙伴们猛戳下面的链接观赏进阶内容:
- SwiftUI 动画进阶:实现行星绕圆周轨道运动
- 如何为 Apple 官方 SwiftUI 示例中的图表元素加上首显动画?
- SwiftUI4.0有趣的动画升级:新iOS16视图内容过渡动画
- SwiftUI如何模拟视图发光增大的动画效果
- 阅读第三方源代码解决SwiftUI弹出视图无动画以及List被诡异重建的问题
4. 暗度陈仓:用动画(Animation)代替过渡(Transition)
对于上面过渡(Transition)动画的这种“怪癖”,我们有一些解决办法来绕过它。不过,它们大多比较复杂,那么有没有简单的方法呢?
答案是肯定的!
其实,SwiftUI 中的普通动画与过渡动画是非常类似的,从本质上来说:在播放动画时前者会保持视图“稳定”,而后者会导致视图被插入或删除。
有了这一思路,我们就可以轻松的将过渡动画转换为普通的动画了:
Section("同时嵌入在 NavigationStack 或 List 中") {VStack {Circle().foregroundStyle(.green).frame(width: 100, height: 100).scaleEffect(magic ? .init(width: 1, height: 1) : .zero)Spacer()Text("利用普通动画解决过渡动画丢失的问题")}.frame(height: 200)
}
从上面的代码可以看出,我们将原先绿色 Circle 上的过渡动画转换成了在视图尺寸上缩放的普通动画效果:
同样,对于博文开头 WorryObject 选择过渡动画缺失的情况,我们也可以如法炮制:
Image(systemName: "checkmark.circle.fill").foregroundStyle(.green.gradient).font(.title3.bold()).scaleEffect(selectingWorryObjectID == wObject.oid ? .init(width: 1, height: 1) : .zero).matchedGeometryEffect(id: 1, in: ns, isSource: selectingWorryObjectID == wObject.oid)
最后运行一下,在 Xcode 预览中欣赏一番我们的最终成果吧:
现在,对于那些 SwiftUI 中过渡动画失灵又无计可施的撸码场景我们也可以轻松应对了,棒棒哒!💯
想要进一步系统地学习 Swift 开发的小伙伴们,可以来我的《Swift 语言开发精讲》专栏逛一逛哦:
- 《Swift 语言开发精讲》
总结
在本篇博文中,我们进一步讨论了 SwiftUI 过渡动画在什么场景下可能会掉链子,并用一招将其彻底驯服。
感谢观赏,再会啦!😎
相关文章:

白玉微瑕:闲谈 SwiftUI 过渡(Transition)动画的“口是心非”(下)
概述 秃头小码农们都知道,SwiftUI 不仅仅是一个静态 UI 构建框架那么简单,辅以海量默认或自定义的动画和过渡(Transition)特效,我们可以将 App 界面的绚丽升华到极致。 不过,目前 SwiftUI 中的过渡&#x…...

论文:深度可分离神经网络存内计算处理芯片
引言:SRAM - CIM芯片在处理深度可分离神经网络时面临的挑战 深度可分离卷积(Depthwise separable convolution, DSC)由逐深度卷积(DW)和逐点卷积(PW)组成,逐深度卷积用于提取空间特征ÿ…...

hdrnet,Deep Bilateral Learning for Real-Time Image Enhancement解读
论文、代码和ppt地址:Deep Bilateral Learning for Real-Time Image Enhancement 论文使用的数据集: HDR: 这是一个复杂的摄影管道,包括色彩校正、自动曝光、去雾和色调映射等操作。 MIT “FiveK” 数据集: 这个数据集由 Bychkovsky 等人 提…...

Android系统开发(十五):从 60Hz 到 120Hz,多刷新率进化简史
引言 欢迎来到“帧率探索实验室”!今天,我们要聊聊 Android 11 中对多种刷新率设备的支持。你可能会问:“这和我写代码有什么关系?”别急,高刷新率不仅仅让屏幕更顺滑,还会直接影响用户体验。想象一下&…...
js判断一个数组对象中是否有相同的值
let userTitleLevelList[{title:医生,code:20},{title:老师,code:21}]; 如果一个数组对象格式如上面。如果有一样的对象就提示。即:title和code都是一样的内容、 const hasDuplicate userTitleLevelList.some((item, index, array) > { return array.filter(…...

基于深度学习的视觉检测小项目(十五) 用户的登录界面
用户管理离不开的是消息框(QMessageBox)和对话框(QDialog),比如对话框用于用户名和密码输入,消息框用于提示登录成功、密码错误。 • 基础知识:PySide6(PyQT5)的常用对话…...

redis-排查命中率降低问题
1.命中率降低带来的问题 高并发系统,当命中率低于平常的的运行情况,或者低于70%时,会产生2个影响。 有大量的请求需要查DB,加大DB的压力;影响redis自身的性能 不同的业务场景,阈值不一样,一般…...

ui文件转py程序的工具
源博客连接: PyCharm中利用外部工具uic转成的py文件,里面全是C代码,并非python类型的代码,导致大量报错。。。_pyside6-uic为什么把ui转为了c-CSDN博客 如果想把ui文件转为py文件,首先设置pycharm的外部工具…...

Alluxio 联手 Solidigm 推出针对 AI 工作负载的高级缓存解决方案
作者:Wayne Gao, Yi Wang, Jie Chen, Sarika Mehta Alluxio 作为全球领先的 AI 缓存解决方案供应商, 提供针对 GPU 驱动 AI 负载的高速缓存。其可扩展架构支持数万个节点,能显著降低存储带宽的消耗。Alluxio 在解决 AI 存储挑战方面的前沿技…...
Oracle 数据库常见字段类型大全及详细解析
在工作期间会遇到数据库建表的业务,经常会使用复制粘帖等操作,而不清楚数据库的字段类型。本文记录了 Oracle 数据库常见字段类型,根据不同的数据需求,可以选择不同的字段类型来存储数据。 文章目录 一、字符类型(Char…...

U3D的.Net学习
Mono:这是 Unity 最初采用的方式,它将 C# 代码编译为中间语言 (IL),然后在目标平台上使用虚拟机 (VM) 将其转换为本地机器码执行。 IL2CPP:这是一种较新的方法,它会将 C# 代码先编译为 C 代码,再由 C 编译器…...

Tomcat下载配置
目录 Win下载安装 Mac下载安装配置 Win 下载 直接从官网下载https://tomcat.apache.org/download-10.cgi 在圈住的位置点击下载自己想要的版本 根据自己电脑下载64位或32位zip版本 安装 Tomcat是绿色版,直接解压到自己想放的位置即可 Mac 下载 官网 https://tomcat.ap…...
adb常用指令(完整版)
1、adb devices 查看是否连接到设备 2、adb install [-r] [-s] 安装app,-r强制,-s安装sd卡上 3、adb uninstall [-k] 卸载app,-k保留配置和参数 4、adb push 把本地文件上传设备 5、adb pull 下载文件到本地 6、cd D:\sdk\platform-tool…...
大数据学习(36)- Hive和YARN
&&大数据学习&& 🔥系列专栏: 👑哲学语录: 承认自己的无知,乃是开启智慧的大门 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言📝支持一下博主哦ᾑ…...
C# ASP.NET MVC项目内使用ApiController
1.在App_Start文件夹新建WebApiConfig.cs文件,建立webApi路由的注册方法。 using System.Web.Http;namespace PrivilegeManager {public class WebApiConfig{public static void Register(HttpConfiguration config){config.MapHttpAttributeRoutes();config.Route…...
Kafka 入门与应用实战:吞吐量优化与与 RabbitMQ、RocketMQ 的对比
前言 在现代微服务架构和分布式系统中,消息队列作为解耦组件,承担着重要的职责。它不仅提供了异步处理的能力,还能确保系统的高可用性、容错性和扩展性。常见的消息队列包括 Kafka、RabbitMQ 和 RocketMQ,其中 Kafka 因其高吞吐量…...
“推理”(Inference)在深度学习和机器学习的语境
“推理”(Inference)在深度学习和机器学习的语境中,是指使用经过训练的模型对新数据进行预测的过程。将其简单地理解为“模型的应用阶段”。在这一阶段,我们不再进行模型训练,而是利用已训练好且保存下来的模型来获取对…...
字节腾讯阿里大厂面经汇总:Java集合(容器)大厂面试题及参考答案
ArrayList 的扩容机制以及删除操作的时间复杂度 ArrayList 是 Java 中非常常用的一个集合类,它是基于数组实现的动态数组。当我们创建一个 ArrayList 时,如果不指定初始容量,它会有一个默认的初始容量(通常是 10)。当我们向 ArrayList 中添加元素时,如果元素的数量达到了…...

数据结构(初阶)(一)----算法复杂度
算法复杂度 算法复杂度数据结构算法算法效率复杂度的概念 数据结构 数据结构(Data Structure)是计算机存储、组织数据的⽅式,指相互之间存在⼀种或多种特定关系的数据元素的集合。没有⼀种单⼀的数据结构对所有⽤途都有⽤,所以我们要学各式各样的数据结…...
构建高效稳定的网络环境
概述 网络技术是当今IT行业的重要组成部分,构建高效稳定的网络环境对于企业、个人和互联网发展至关重要。本文将探讨网络技术中的关键要素,包括网络协议、网络架构、网络安全和网络优化,并提供实用的技巧和最佳实践,以帮助您构建…...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...
工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配
AI3D视觉的工业赋能者 迁移科技成立于2017年,作为行业领先的3D工业相机及视觉系统供应商,累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成,通过稳定、易用、高回报的AI3D视觉系统,为汽车、新能源、金属制造等行…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...

什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...

企业如何增强终端安全?
在数字化转型加速的今天,企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机,到工厂里的物联网设备、智能传感器,这些终端构成了企业与外部世界连接的 “神经末梢”。然而,随着远程办公的常态化和设备接入的爆炸式…...

均衡后的SNRSINR
本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt 根发送天线, n r n_r nr 根接收天线的 MIMO 系…...
JAVA后端开发——多租户
数据隔离是多租户系统中的核心概念,确保一个租户(在这个系统中可能是一个公司或一个独立的客户)的数据对其他租户是不可见的。在 RuoYi 框架(您当前项目所使用的基础框架)中,这通常是通过在数据表中增加一个…...

AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机
这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机,因为在使用过程中发现 Airsim 对外部监控相机的描述模糊,而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置,最后在源码示例中找到了,所以感…...
现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?
现有的 Redis 分布式锁库(如 Redisson)相比于开发者自己基于 Redis 命令(如 SETNX, EXPIRE, DEL)手动实现分布式锁,提供了巨大的便利性和健壮性。主要体现在以下几个方面: 原子性保证 (Atomicity)ÿ…...
WebRTC从入门到实践 - 零基础教程
WebRTC从入门到实践 - 零基础教程 目录 WebRTC简介 基础概念 工作原理 开发环境搭建 基础实践 三个实战案例 常见问题解答 1. WebRTC简介 1.1 什么是WebRTC? WebRTC(Web Real-Time Communication)是一个支持网页浏览器进行实时语音…...