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

白玉微瑕:闲谈 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 过渡动画会消失不见,变为“鸟迹虫丝”。

在下面的代码中,我们测试的两枚绿色圆形分别放在了不同的容器中:

  1. 顶部的圆形放在 NavigationStack 和 List 中;
  2. 底部的圆形只放在了 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)组成,逐深度卷积用于提取空间特征&#xff…...

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的外部工具&#xf…...

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

&&大数据学习&& 🔥系列专栏: 👑哲学语录: 承认自己的无知,乃是开启智慧的大门 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言📝支持一下博主哦&#x1f91…...

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行业的重要组成部分,构建高效稳定的网络环境对于企业、个人和互联网发展至关重要。本文将探讨网络技术中的关键要素,包括网络协议、网络架构、网络安全和网络优化,并提供实用的技巧和最佳实践,以帮助您构建…...

使用Edge打开visio文件

使用Edge打开visio文件 打开Edge浏览器搜索‘vsdx edge’ 打开第一个搜索结果 Microsoft Support 根据上述打开的页面进行操作 第一步:安装Visio Viewer 第二步:添加注册表 桌面新增文本文件,将下面的内容放入新建文本中,修…...

ChatGPT Prompt 编写指南

一、第一原则:明确的意图​ 你需要明确地表达你的意图和要求,尽可能具体、描述性、详细地描述所需的上下文、你期望的结果等。你的要求越明确,越有希望获得你想要的答案。​ 糟糕的案例 ❌​ ​ 写一首关于 OpenAI 的诗。​ ​ 更好的案…...

蚁群算法 (Ant Colony Optimization) 算法详解及案例分析

蚁群算法 (Ant Colony Optimization) 算法详解及案例分析 目录 蚁群算法 (Ant Colony Optimization) 算法详解及案例分析1. 引言2. 蚁群算法 (ACO) 算法原理2.1 蚂蚁觅食行为2.2 算法步骤2.3 数学公式3. 蚁群算法的优势与局限性3.1 优势3.2 局限性4. 案例分析4.1 案例1: 旅行商…...

安卓动态设置Unity图形API

命令行方式 Unity图像api设置为自动,安卓动态设置Vulkan、OpenGLES Unity设置 安卓设置 创建自定义活动并将其设置为应用程序入口点。 在自定义活动中,覆盖字符串UnityPlayerActivity。updateunitycommandlineararguments (String cmdLine)方法。 在该方法中,将cmdLine…...

通信协议—WebSocket

一、WebSocket编程概念 1.1 什么是WebSocket WebSocket 是一种全双工通信协议,允许在客户端(通常是浏览器)和服务器之间建立持久连接,以实现实时的双向通信。它是 HTML5 标准的一部分,相比传统的 HTTP 请求&#xff…...

helm推送到harbor私有库--http: server gave HTTP response to HTTPS client

harbor私有库访问的是http模式 harbor 2.8版本以上可以存储helm镜像 docker镜像推送的时候需要docker端配置insecure-registries 发现helm推送只能在harbor部署的本机使用localhost才能推送成功,即 helm push xxx.tgz oci://localhost:80/library 使用helm pus…...

数据结构——实验一·线性表

海~~欢迎来到Tubishu的博客🌸如果你也是一名在校大学生,正在寻找各种变成资源,那么你就来对地方啦🌟 Tubishu是一名计算机本科生,会不定期整理和分享学习中的优质资源,希望能为你的编程之路添砖加瓦⭐&…...

快速搭建深度学习环境(Linux:miniconda+pytorch+jupyter notebook)

本文基于服务器端环境展开,使用的虚拟终端为Xshell。 miniconda miniconda是Anaconda的轻量版,仅包含Conda和Python,如果只做深度学习,可使用miniconda。 [注]:Anaconda、Conda与Miniconda Conda:创建和管…...

OpenCV相机标定与3D重建(66)对立体匹配生成的视差图(disparity map)进行验证的函数validateDisparity()的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 使用左右检查来验证视差。矩阵 “cost” 应该由立体对应算法计算。 cv::validateDisparity 函数是 OpenCV 库中用于对立体匹配生成的视差图&…...

2025年新开局!谁在引领汽车AI风潮?

汽车AI革命已来。 在2025年伊始开幕的CES展上,AI汽车、AI座舱无疑成为了今年汽车行业的最大热点。其中不少车企在2025年CES上展示了其新一代AI座舱,为下一代智能汽车的人机交互、场景创新率先打样。 其中,东软集团也携带AI驱动、大数据支撑…...