[SwiftUI 开发] 构建带有动画的图片瀑布流效果

news2024/11/14 7:06:28

在移动应用程序中,图片瀑布流布局是一种常见的设计模式,它不仅能够以网格的形式显示大量图片,还能允许用户点击图片进行全屏查看。
在下文中,将详细介绍如何使用 SwiftUI 构建一个带有点击动画效果的图片瀑布流布局,并通过 matchedGeometryEffect 实现图片从列表到全屏的平滑过渡。

效果概述

用户可以看到一个由多张图片组成的瀑布流布局,图片按列排列。当用户点击其中一张图片时,图片会在全屏模式下显示,并带有平滑的动画过渡。用户可以再次点击全屏图片,返回瀑布流视图。

核心技术点

  1. 瀑布流布局:使用 HStack 和 VStack 创建两列图片。
  2. 点击事件和动画过渡:通过 onTapGesture 实现点击事件,并使用 matchedGeometryEffect 实现动画效果。
  3. 全屏图片显示:使用 GeometryReader 调整全屏图片的布局,并在背景使用模糊效果。

实现步骤

1. 项目初始化

首先,在 Xcode 中创建一个新的 SwiftUI 项目。为了简单起见,我们在 ContentView 中实现所有功能。在实际项目中,你可以根据需求将代码拆分到多个视图中。

 

2. 构建基础的图片数据

假设我们有一组图片,命名为 "351" 到 "379"(假设这些图片资源已包含在项目中)。我们将这组图片存储在一个数组中。

struct ContentView: View {
    // 图片名称数组
    var imageNames = ["351", "352", "353", "354", "355", "356", "357", "358", "359", "360", "370", "371", "372", "373", "374", "375", "376", "377", "378", "379"]
    
    // 控制全屏展示图片的状态
    @State var show = false
    
    // 使用 @Namespace 修饰符定义动画作用域,用于 `matchedGeometryEffect` 共享动画效果
    @Namespace var animation
    
    // 当前被点击的图片名称
    @State var cItem = ""
  • imageNames:一个数组,用于存储图片的名称。
  • @State var show:一个布尔状态,控制是否显示全屏图片。
  • @Namespace var animation:命名空间,用于 matchedGeometryEffect 动画效果。
  • @State var cItem:存储当前被点击的图片名称。

 

3. 布局瀑布流图片

为了实现图片的瀑布流布局,我们将图片分成两列。使用 HStack 创建一个水平的图片容器,在其中嵌入两个 VStack 用于垂直排列图片。

var body: some View {
    // 使用 ScrollView 允许垂直滚动,隐藏滚动指示器
    ScrollView(showsIndicators: false) {
        // 两列图片的水平布局,使用 HStack 进行布局
        HStack(alignment: .top, spacing: 5) {
            // 第一列图片,使用数组的前一半
            createColumn(with: imageNames.prefix(imageNames.count / 2))
            
            // 第二列图片,使用数组的后一半
            createColumn(with: imageNames.suffix(imageNames.count / 2))
        }
    }
    .padding(.horizontal, 5) // 为 ScrollView 添加一些填充
    .overlay {
        if show {
            fullScreenImageOverlay // 全屏图片展示
        }
    }
    .edgesIgnoringSafeArea(.all) // 使图片铺满全屏
}

在这里我们使用 ScrollView 允许图片垂直滚动,并隐藏滚动指示器。HStack 将两列图片横向排列,padding(.horizontal, 5) 为整体视图添加左右间距。

 

4. 创建图片列

为了避免代码重复,我们将创建图片列的代码提取到一个函数中,这个函数通过传递图片名称数组的一部分来生成列布局。

// 创建列视图的函数,将图片数组传入,并通过 VStack 进行竖直排列
func createColumn(with items: ArraySlice<String>) -> some View {
    VStack(spacing: 5) {
        // 遍历图片名称数组,并为每张图片创建一个视图
        ForEach(items, id: \.self) { item in
            Image(item) // 显示图片
                .resizable() // 使图片可以调整大小
                .scaledToFill() // 保持图片比例并填充视图
                .matchedGeometryEffect(id: item, in: animation) // 绑定几何动画效果
                .frame(minWidth: 0, maxWidth: .infinity) // 最大宽度为可用空间的宽度
                .frame(maxHeight: .infinity) // 最大高度设为无限,允许视图扩展
                .cornerRadius(5) // 为图片添加圆角
                .onTapGesture {
                    // 当图片被点击时,更新 cItem 为当前图片名称,并触发动画切换 show 状态
                    cItem = item
                    withAnimation(.spring()) {
                        show = true // 切换全屏展示状态
                    }
                }
        }
    }
}

主要说明

  • ForEach 用于遍历传入的图片数组并为每张图片创建视图。
  • Image(item) 加载图片,并使用 .resizable() 和 .scaledToFill() 保证图片适应视图大小。
  • matchedGeometryEffect 实现点击后图片动画的平滑过渡。
  • onTapGesture:当用户点击图片时,记录当前点击的图片名称,并将 show 状态改为 true 以显示全屏图片。

 

5. 全屏图片显示

当用户点击图片时,全屏展示该图片,并带有动画效果。我们使用 GeometryReader 以适应设备屏幕大小,并设置 matchedGeometryEffect 来确保图片从列表过渡到全屏时有平滑的动画效果。

// 全屏图片展示的视图,当 show 为 true 时显示
var fullScreenImageOverlay: some View {
    GeometryReader { geometry in
        // 通过几何读取器获取设备尺寸并动态调整图片大小
        Image(cItem) // 显示当前被点击的图片
            .resizable() // 使图片可以调整大小
            .scaledToFit() // 保持图片比例并适应全屏
            .matchedGeometryEffect(id: cItem, in: animation) // 绑定几何动画效果
            .frame(width: geometry.size.width, height: geometry.size.height) // 使用设备的宽高进行布局
            .background(.thinMaterial) // 使用薄模糊背景效果
            .onTapGesture {
                // 当全屏图片被点击时,切换 show 状态,退出全屏
                withAnimation(.spring()) {
                    show = false
                }
            }
    }
}

在这里,我们使用 GeometryReader 读取设备的宽高,以调整全屏图片的大小,并确保其按比例适应屏幕。background(.thinMaterial) 为全屏图片设置了模糊背景效果,使用户的注意力集中在图片上。

 

6. 运行效果

最终实现的效果是:用户可以看到两列垂直排列的图片,点击任意图片时,该图片会平滑地过渡到全屏显示,并且背景会变为模糊效果,给用户带来沉浸式的视觉体验。再次点击全屏图片,图片会返回到原来的位置,并恢复到瀑布流布局。

 

结论

通过 SwiftUI 强大的布局和动画功能,我们可以轻松实现复杂的 UI 交互效果。matchedGeometryEffect 允许我们在不同视图之间创建共享的几何效果,保证动画的流畅性和一致性。而 GeometryReader 则让我们能够动态适应不同设备的屏幕大小。在这个示例中,完整地展示了如何构建一个功能强大且具有吸引力的图片瀑布流布局。

通过进一步优化代码和添加更多功能(如图片缩放、滑动关闭全屏等),你可以创建出更加丰富的用户体验。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2110290.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

B站视频下载教程

文章目录 1.确保浏览器下载了tampermonkey(油猴)2.下载插件3.下载mtorix4.浏览器刷新并下载视频 1.确保浏览器下载了tampermonkey(油猴) 至于这个步骤可以自行搜索一下很简单&#xff0c;讲油猴固定在状态栏&#xff0c;显示如下 2.下载插件 1.进入greasyFork 2.搜索B站视…

【Unity-Lua】音乐播放器循环滚动播放音乐名

前言&#xff1a;Unity中UI节点 图1 如上所示&#xff0c;一开始本来是打算用ScrollView做的&#xff0c;觉得直接计算对应的文本位置就行&#xff0c;所以没用ScrollRect来做&#xff0c;可以忽略Scroll&#xff0c;Viewport这些名字。如下图&#xff1a;需要在一个背景Image…

多级别分销平台怎么做 千店系统设计关键要点

创建多级别分销平台可以帮助企业拓展市场并激励分销商&#xff0c;多级别分销商城的良好设计可以助力企业的营销事半功倍。今天&#xff0c;商淘云为您分享千店系统设计的三大关键要点。 首先&#xff0c;选择合适的平台和技术工具至关重要。使用像商淘云供应链这样的电商平台&…

睿赛德科技携手先楫共创RISC-V生态|RT-Thread EtherCAT主从站方案大放异彩

日前&#xff0c;在先楫HPM6E00技术日上&#xff0c;睿赛德科技&#xff08;RT-Thread&#xff09;向广大工业用户展示了多年来双方在RISC-V生态领域的合作历程和成果&#xff0c;同时睿赛德科技携手先楫半导体首次推出了基于HPM6800处理器的EtherCAT主站解决方案&#xff0c;吸…

Uniapp + Vite + Vue3 + uView + Pinia 实现自定义底部 Tabbar(最新保姆级教程)

Uniapp Vite Vue3 uView Pinia 实现自定义底部 Tabbar&#xff08;最新保姆级教程&#xff09; 1、效果展示2、环境准备2.1 新建 uniapp 项目2.2. 安装 uView2.3 安装 pinia 3. 配置环境4. 创建目录结构5、编写 pages.json 页面路由6、编写 tabbar.js 状态数据7、编写 tabb…

Java-IDEA模拟一个Redis服务器,与Redis客户端进行一次简单的交互。默认端口号:6379

首先要了解Redis的交互协议。 摘抄&#xff1a; 简单字符串&#xff08;Simple Strings&#xff09;: 以 “” 开头&#xff0c;例如 “OK\r\n” 表示一个成功的响应。错误&#xff08;Errors&#xff09;: 以 “-” 开头&#xff0c;例如 “-ERR unknown command\r\n” 表示一…

操作系统概述及特征

&#xff08;较为浅显的了解操作系统&#xff0c;适合小白&#xff09;&#xff1b; 目录 1. 操作系统概述 1.1 操作系统 1.2 系统软件 1.3 主要作用 2. 操作系统的特征 ​编辑 2.1 并发性​编辑 2.2 并行​编辑 2.3 共享性 2.3.1 共享概述 2.3.2 共享与并发的关系…

【机器学习】朴素贝叶斯网络的基本概念以及朴素贝叶斯网络在python中的实例

引言 文章目录 引言一、朴素贝叶斯网络1.1 基本概念1.1.1 节点1.1.2 边&#xff08;Edges&#xff09;1.1.3 条件独立性 1.2 特点1.2.1 结构简单1.2.2 易于理解和实现1.2.3 计算效率高 1.3 应用1.4 数学表示1.5 局限性 二、朴素贝叶斯网络在python中的实例2.1 实例背景2.2 实现…

LangChain 最新版入门实战-v0.2

LangChain 基础入门文档 1. 认识 LangChain LangChain 是一个基于大型语言模型&#xff08;LLM&#xff09;的应用开发框架。它通过两种方式规范和简化了使用大型语言模型的方式&#xff1a; 集成&#xff1a;让语言模型能够使用更多的信息。 代理&#xff1a;让语言模型能够…

Linux 磁盘增加分区并挂载

说明 目的&#xff1a;该篇文章主要是实操后为了备忘 原因&#xff1a;为了方便&#xff0c;直接使用已有模板创建了虚拟机。没想到创建的新机器给了300G磁盘&#xff0c;实际只有2个分区且只使用了100G。以下为我实操后成功增加分区并挂载的步骤。 增加分区 指定操作对象&a…

如何快速写文献综述

真实参考文献的AI论文生成器&#xff1a;AIPaperDone - AI 万字论文生成 在本文中,你将学习如何为不同的学术领域撰写文献综述。 请注意: 文献综述并不是关于小说或诗歌等文学作品的。当我们说"文献",我们指的是某个领域的"研究"。撰写文献综述意味着收集…

【鸿蒙】HarmonyOS NEXT星河入门到实战3-ArkTS界面起步开发

目录 一、界面开发布局思路 二、组件的属性方法 三、字体颜色 四、文字溢出省略号、行高 五、Image图片组件 六、输入框与按钮 七、综合实战- 华为登录 八、设计资源-svg图标 前言&#xff1a;HarmonyOS NEXTArkTS界面开发起步。开发工具:仍然是 DevEco Studio 学习界面…

Android 使用JSON动画:Lottie框架基本使用

Lottie是什么? GitHub的一种跨平台动画解决方案三方框架 使用? 3步 1.引入最新的依赖:https://github.com/airbnb/lottie-android 我写文章时最新版本是6.5.2 添加到 app/build.gradle 文件的以下方法中dependencies {//lottie 动画implementation com.airbnb.android:l…

JavaScript DOM事件流之捕获与冒泡

DOM事件流——捕获与冒泡 网页是由一个一个元素组成的&#xff0c;正如我们肉眼所见&#xff0c;网页上的元素存在包含关系&#xff0c;简单的点击又怎么确定到底谁来触发响应呢&#xff1f;想象一下&#xff0c;在纸上画了两个大小不同的同心圆&#xff0c;然后用手指指向它里…

第45篇 汇编语言实现中断<一>

Q&#xff1a;DE2-115_Computer System的异常与中断有哪些特点呢&#xff1f; A&#xff1a;DE2-115 Computer系统中的Nios II处理器复位地址为0x00000000。用于处理其它所有普通异常&#xff0c;例如除0以及硬件IRQ中断的地址为0x00000020。Nios II处理器的异常和硬件IRQ中…

C++和OpenGL实现3D游戏编程【连载8】——纹理文字实现与优化

C++和OpenGL实现3D游戏编程【连载8】——纹理文字实现与优化 1、本节达到的效果 上一节课我们介绍了在opengl中文字的显示方法,但显示出来的文字无法旋转,在某些特定游戏要求下,文字是需要进行旋转的,那么这一节课我们介绍一下纹理文字的高级使用方法,将文字生成纹理,达…

一文搞懂性能测试

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 性能测试概念 我们经常看到的性能测试概念&#xff0c;有人或称之为性能策略&#xff0c;或称之为性能方法&#xff0c;或称之为性能场景分类&#xff0c;大概…

mysql和pg等数据库之间的数据迁移实战分享

mysql和pg等数据库之间的数据迁移是常见的问题&#xff1a;比如一开始使用Oracle&#xff0c;后来想使用mysql&#xff0c;而且需要把Oracle数据库的数据迁移到mysql里面&#xff1b;后期有想使用pg数据库&#xff0c;同时需要把Mysql数据库的数据迁移到pgl里面&#xff0c;等等…

shell脚本编写之函数

shell中的函数定义比较简单&#xff0c;定义函数名可以没有类型&#xff0c;函数返回值可有可无&#xff0c;如果有返回值&#xff0c;必须返回整数n&#xff08;0~255&#xff09;。同时&#xff0c;函数的定义必须放在shell脚本的开头部分&#xff0c;只有函数被shell解释器发…

【微机】DOSBox在windows上的安装和masm的配置

本文首发于 ❄️慕雪的寒舍 最近学校学习微型计算机原理与接口技术&#xff0c;需要用到DOSBox来模拟DOS环境进行汇编编程的学习。 本文记录了如何在windows11/10上安装DOSBox0.74并配置masm5 1.安装 这两个软件我打包上传到了百度云盘。放心&#xff0c;加起来也就2mb&…