ios swift5 collectionView 瀑布流(两列)
文章目录
- 1.瀑布流
- 1.1 demo地址
- 1.2 记得把部署的最低版本由8改成11,13甚至更高。不然编译会报错
- 2.动态计算图片和文字的高度
1.瀑布流
1.1 demo地址
CollectionViewWaterfallLayout - github

1.2 记得把部署的最低版本由8改成11,13甚至更高。不然编译会报错

2.动态计算图片和文字的高度
//可以正常使用
import UIKit
import SnapKit
class ConcernedVC: UICollectionViewController, UICollectionViewDelegateFlowLayout {let cellReuseIdentifier = "WaterfallCell"let itemsPerRow: CGFloat = 2let sectionInsets = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)let itemSpacing: CGFloat = 10 // Spacing between items in the same columnvar columnHeights: [CGFloat] = [0, 0] // Heights of the two columnslet sampleData: [(image: UIImage, text: String)] = [(UIImage(named: "img_about us_app")!, "Sample Text 1"),(UIImage(named: "banner")!, "Sample Text 2adfahdfkajdfiahdofhadoifhaodhfaoihdfhasdifhaidhfapfdhiashf"),(UIImage(named: "img_about us_app")!, "Sample Text 1"),(UIImage(named: "banner")!, "Sample Text 2adfahdfkajdfiahdofhadoifhaodhfaoihdfhasdifhaidhfapfdhiashf"),(UIImage(named: "img_about us_app")!, "Sample Text 1"),(UIImage(named: "banner")!, "Sample Text 2adfahdfkajdfiahdofhadoifhaodhfaoihdfhasdifhaidhfapfdhiashf"),(UIImage(named: "img_about us_app")!, "Sample Text 1"),(UIImage(named: "img_about us_app")!, "Sample Text 1"),// Add more sample data here]override func viewDidLoad() {super.viewDidLoad()// let layout = UICollectionViewFlowLayout() // Create a layout instance
// collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout) // Initialize UICollectionView with the layoutcollectionView.delegate = selfcollectionView.dataSource = selfcollectionView.register(WaterfallCell.self, forCellWithReuseIdentifier: cellReuseIdentifier)collectionView.backgroundColor = .white}// MARK: UICollectionViewDataSourceoverride func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {return sampleData.count}override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellReuseIdentifier, for: indexPath) as! WaterfallCelllet data = sampleData[indexPath.item]cell.configure(with: data)return cell}// MARK: UICollectionViewDelegateFlowLayoutfunc collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {let paddingSpace = sectionInsets.left * (itemsPerRow + 1)let availableWidth = collectionView.frame.width - paddingSpacelet widthPerItem = availableWidth / itemsPerRowlet data = sampleData[indexPath.item]let imageAspectRatio = data.image.size.width / data.image.size.heightlet textHeight = data.text.height(withConstrainedWidth: widthPerItem - 16, font: UIFont.systemFont(ofSize: 14))let imageHeight = min(200, widthPerItem / imageAspectRatio) // Limit image heightlet totalHeight = imageHeight + textHeight + 16return CGSize(width: widthPerItem, height: totalHeight)}func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {return sectionInsets}func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {return sectionInsets.left}func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {return sectionInsets.left}
}
class WaterfallCell: UICollectionViewCell {let imageView = UIImageView()let label = UILabel()override init(frame: CGRect) {super.init(frame: frame)contentView.backgroundColor = .yellowcontentView.addSubview(imageView)imageView.contentMode = .scaleAspectFillimageView.clipsToBounds = truecontentView.addSubview(label)label.numberOfLines = 2label.font = UIFont.systemFont(ofSize: 14)}required init?(coder: NSCoder) {fatalError("init(coder:) has not been implemented")}func configure(with data: (image: UIImage, text: String)) {imageView.image = data.imagelabel.text = data.textlet imageAspectRatio = data.image.size.width / data.image.size.heightlet imageHeight = frame.width / imageAspectRatioimageView.frame = CGRect(x: 0, y: 0, width: frame.width, height: imageHeight)label.frame = CGRect(x: 0, y: imageHeight + 8, width: frame.width, height: labelHeight)}private var labelHeight: CGFloat {let labelWidth = frame.width - 16return label.text?.height(withConstrainedWidth: labelWidth, font: UIFont.systemFont(ofSize: 14)) ?? 0}
}
extension String {func height(withConstrainedWidth width: CGFloat, font: UIFont) -> CGFloat {let constraintRect = CGSize(width: width, height: .greatestFiniteMagnitude)let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [NSAttributedString.Key.font: font], context: nil)return ceil(boundingBox.height)}
}//使用
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .vertical
let vc = ConcernedVC(collectionViewLayout: layout)
相关文章:
ios swift5 collectionView 瀑布流(两列)
文章目录 1.瀑布流1.1 demo地址1.2 记得把部署的最低版本由8改成11,13甚至更高。不然编译会报错 2.动态计算图片和文字的高度 1.瀑布流 1.1 demo地址 CollectionViewWaterfallLayout - github 1.2 记得把部署的最低版本由8改成11,13甚至更高。不然编译会报错 2.动态计算图片和…...
创建一个简单的HTML Viewer应用程序
使用wxPython和内嵌浏览器来创建一个简单的HTML Viewer应用程序。 在本篇文章中,我们将使用Python和wxPython模块来创建一个简单的HTML Viewer应用程序。这个应用程序可以让用户输入HTML内容,并在内嵌浏览器中显示该内容的效果。 准备工作 在开始之前…...
无公网IP,公网SSH远程访问家中的树莓派教程
文章目录 前言 如何通过 SSH 连接到树莓派步骤1. 在 Raspberry Pi 上启用 SSH步骤2. 查找树莓派的 IP 地址步骤3. SSH 到你的树莓派步骤 4. 在任何地点访问家中的树莓派4.1 安装 Cpolar内网穿透4.2 cpolar进行token认证4.3 配置cpolar服务开机自启动4.4 查看映射到公网的隧道地…...
「UG/NX」Block UI 超级截面SuperSection
✨博客主页何曾参静谧的博客📌文章专栏「UG/NX」BlockUI集合📚全部专栏「UG/NX」NX二次开发「UG/NX」BlockUI集合「VS」Visual Studio「QT」QT5程序设计「C/C+&#...
高层建筑全景vr火灾隐患排查模拟培训软件助力群众防范火灾伤害
随着城市化进程的加快,楼宇建筑的数量也在不断增加。然而,楼宇消防安全问题也日益突出。为了提高楼宇员工和居民的消防安全意识,楼宇VR消防安全教育培训应运而生。VR安全培训公司深圳华锐视点制作的楼宇vr消防安全教育培训,包括消…...
【WPF】 本地化的最佳做法
【WPF】 本地化的最佳做法 资源文件英文资源文件 en-US.xaml中文资源文件 zh-CN.xaml 资源使用App.xaml主界面布局cs代码 App.config辅助类语言切换操作类资源 binding 解析类 实现效果 应用程序本地化有很多种方式,选择合适的才是最好的。这里只讨论一种方式&#…...
VS2017编译同事VS2022创建的库,报错无法运行rc.exe
项目场景: 项目场景:有一个qt的版本,迁移到VS中进行开发编译,同事使用的是VS2022已经编译成功。但是拷贝到我电脑,我使用VS2017打开编译,却报错:报错无法运行rc.exe。 原因分析: 1.…...
Leetcode49. 字母异位词分组
给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。 字母异位词 是由重新排列源单词的所有字母得到的一个新单词。 解题思路:计数 思路:题意是字符串的字符都是小写,可以对每个字符串统计其中字符的…...
设计模式之工厂方法模式(FactoryMethod)
一、概述 定义一个用于创建对象的接口,让子类决定实例化哪一个类。FactoryMethod使一个类的实例化延迟到其子类。 二、适用性 1.当一个类不知道它所必须创建的对象的类的时候。 2.当一个类希望由它的子类来指定它所创建的对象的时候。 3.当类将创建对象的职责委…...
python的进度条tqdm库,显示时进度条不换行设置
问题描述 tqdm库,显示时进度条不要换行,直接在一行里显示当前进度 换行显示: 不换行显示 解决方案(参考链接) 添加参数position0 和 leaveTrue 举例: 修改前: import tqdm import time f…...
spark的使用
spark的使用 spark是一款分布式的计算框架,用于调度成百上千的服务器集群。 安装pyspark # os.environ[PYSPARK_PYTHON]解析器路径 pyspark_python配置解析器路径 import os os.environ[PYSPARK_PYTHON]"D:/dev/python/python3.11.4/python.exe"pip inst…...
力扣:66. 加一(Python3)
题目: 给定一个由 整数 组成的 非空 数组所表示的非负整数,在该数的基础上加一。 最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。 你可以假设除了整数 0 之外,这个整数不会以零开头。 来源:力扣…...
Go的标准库Context理解
作为一个才入门的菜鸟,还没写过真正的 go 项目,要理解这个 Context 还是有点难,不过还是要尝试一下。在 Go http包的Server中,每一个请求在都有一个对应的 goroutine 去处理。请求处理函数通常会启动额外的 goroutine 用来访问后端…...
Nuxt3_1_路由+页面+组件+资源+样式 使用及实例
1、 简介 1.1 开发必备 node版本 v16.10.0 我使用的是16.14.0编辑器推荐使用Volar Extension 的VS code插件Terminal 运行nuxt指令 1.2 环境搭建 安装项目: npx nuxilatest init [first_nuxt3]进入项目目录: cd [first_nuxt3]安装依赖:n…...
Kafka第三课
Flume 由三部分 Source Channel Sink 可以通过配置拦截器和Channel选择器,来实现对数据的分流, 可以通过对channel的2个存储容量的的设置,来实现对流速的控制 Kafka 同样由三大部分组成 生产者 服务器 消费者 生产者负责发送数据给服务器 服务器存储数据 消费者通过从服务器取…...
elasticsearch修改es集群的索引副本数量
前言 最近es集群进行调整,从2节点变成了单节点。所以需要将集群模式改为单点模式,并需要将es 集群的全部索引副本个数改为0,不然会有很多未分配的分片,导致集群状态为 yellow。 具体实践 1. 先将现有的index的副本数量为0个 此…...
【SpringCloud】Ribbon定制化配置
文章目录 使用Ribbon自带负载均衡算法添加负载均衡算法ConfigurationRestTemplate使用上面负载均衡算法 自定义负载均衡算法负载均衡算法实现RestTemplate在Controller中使用该负载均衡算法ServiceIInstance解释 使用Ribbon自带负载均衡算法 添加负载均衡算法Configuration /…...
Mac terminal 每次打开都要重新配置文件
1. 问题描述 每次打开 Terminal,base_profile文件中配置的内容就不生效,需要重新执行source ~/.bash_profile才可以使用。 2. 原因分析 zsh加载的是~/.zshrc文件,而.zshrc 文件中并没有定义任务环境变量。 3. 解决办法 在~/.zshrc文件末尾添…...
el-button实现按钮,鼠标移入显示,移出隐藏
2023.8.18今天我学习了 如何实现鼠标移入显示按钮,鼠标移出隐藏按钮。 效果如图: 鼠标移入时: 鼠标移出时: mouseover //鼠标移入事件 mouseleave //鼠标移出事件 原本我是想直接在el-button写入这两个方法,但是elem…...
uniapp+uview封装小程序请求
提要: uniapp项目引入uview库 此步骤不再阐述 1.创建环境文件 env.js: let BASE_URL;if (process.env.NODE_ENV development) {// 开发环境BASE_URL 请求地址; } else {// 生产环境BASE_URL 请求地址; }export default BASE_URL; 2.创建请求文件 该…...
C# IDisposable:3个致命陷阱+5个最佳实践,你踩过几个?
🔥关注墨瑾轩,带你探索编程的奥秘!🚀 🔥超萌技术攻略,轻松晋级编程高手🚀 🔥技术宝库已备好,就等你来挖掘🚀 🔥订阅墨瑾轩,智趣学习不…...
无数据库版Mirror照妖镜源码解析:如何安全改造为个人图片鉴黄工具
无数据库版Mirror照妖镜源码解析:如何安全改造为个人图片鉴黄工具 在当今内容爆炸的时代,图片审核成为许多个人开发者和内容创作者的刚需。传统解决方案往往依赖复杂的数据库系统和第三方API,而Mirror照妖镜的无数据库设计为轻量级图片审核提…...
YOLOv8自定义检测头踩坑记:手把手教你修复‘NotImplementedError: new_detect task‘错误
YOLOv8自定义检测头实战:从报错到修复的深度解析 当你在YOLOv8框架中尝试添加一个名为new_detect的自定义检测头时,突然遇到NotImplementedError: new_detect task错误,这可能会让你感到困惑。本文将带你深入理解YOLOv8的任务调度机制&#x…...
不用命令行!Win11任务栏图标消失的图形化解决方案(Explorer重启神器推荐)
Win11任务栏图标消失?5种可视化修复方案与深度解析 每次切换虚拟桌面后,Win11任务栏图标集体"失踪"的毛病,堪称微软系统最顽固的"幽灵故障"之一。作为从Windows 95时代就存在的资源管理器痼疾,这个问题在Win1…...
全格式文档智能处理:AnythingLLM的多模态知识管理解决方案
全格式文档智能处理:AnythingLLM的多模态知识管理解决方案 【免费下载链接】anything-llm 这是一个全栈应用程序,可以将任何文档、资源(如网址链接、音频、视频)或内容片段转换为上下文,以便任何大语言模型(…...
MybatisPlus分页插件PaginationInnerInterceptor原理解析与实战配置指南
MybatisPlus分页插件PaginationInnerInterceptor深度剖析与高效实践 当你在Spring Boot项目中处理海量数据时,分页查询就像给数据装上精准导航——而MybatisPlus的PaginationInnerInterceptor正是这个导航系统的核心引擎。不同于简单配置就能用的工具类,…...
基于训练RBF神经网络的车速信息时序预测Matlab模型
✅作者简介:热爱科研的Matlab仿真开发者,擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。🍎 往期回顾关注个人主页:Matlab科研工作室👇 关注我领取海量matlab电子书和…...
省市区县四级联动数据获取指南:基于高德API的geoJSON数据自动更新方案
省市区县四级联动数据获取指南:基于高德API的geoJSON数据自动更新方案 行政区划数据是地理信息系统和数据分析领域的基础要素之一。无论是制作可视化地图、进行区域统计分析,还是开发基于位置的服务应用,准确、实时的行政区划数据都至关重要。…...
保姆级避坑指南:Ubuntu系统下Hadoop HA集群搭建,我踩过的那些SSH和配置文件的“坑”
Ubuntu下Hadoop HA集群搭建:那些教科书不会告诉你的实战陷阱 第一次在Ubuntu上搭建Hadoop HA集群时,我天真地以为照着官方文档就能顺利跑起来。直到SSH连接莫名其妙失败、JournalNode权限报错刷屏、ZKFC死活不启动时,才明白为什么有人说大数据…...
从零开始:用QGIS和PostgreSQL构建交通路线空间数据库(含Python脚本自动化技巧)
从零开始:用QGIS和PostgreSQL构建交通路线空间数据库(含Python脚本自动化技巧) 在交通规划与智慧城市建设的浪潮中,空间数据的高效管理成为技术团队的核心挑战。传统文件存储方式难以应对大规模交通网络数据的实时查询与分析需求&…...
