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

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)&#xff…...

WebRTC从入门到实践 - 零基础教程

WebRTC从入门到实践 - 零基础教程 目录 WebRTC简介 基础概念 工作原理 开发环境搭建 基础实践 三个实战案例 常见问题解答 1. WebRTC简介 1.1 什么是WebRTC? WebRTC(Web Real-Time Communication)是一个支持网页浏览器进行实时语音…...