深入FMMosaicLayout核心:prepareLayout布局计算全流程图解
深入FMMosaicLayout核心prepareLayout布局计算全流程图解【免费下载链接】FMMosaicLayoutA drop-in mosaic collection view layout with a focus on simple customizations.项目地址: https://gitcode.com/gh_mirrors/fm/FMMosaicLayoutFMMosaicLayout 是一款 iOS 马赛克 collection view 布局库。它的 prepareLayout 布局计算流程决定了每个单元格的位置与大小本文用 6 个步骤图解整个计算过程带你快速看懂这套最短列瀑布流算法的精髓。马赛克布局是什么一眼看懂 FMMosaicLayout 的核心能力大多数媒体类 App 都直接使用UICollectionViewFlowLayout结果是整齐划一却略显无聊的方格墙。FMMosaicLayout 借鉴了经典的图片瀑布流算法带来两种单元格尺寸大单元格占满一整列宽视觉冲击力强小单元格两个并排占一列宽形成拼图片效果配合可配置的列数、单元格间距和分区间距最终呈现出错落有致的马赛克拼图。所有布局规则都通过FMMosaicLayoutDelegate协议回调给业务层库本身不关心你展示的是什么内容——这正是即插即用的关键。prepareLayout 布局计算全流程总览6 步排布一个 section整个计算入口是 prepareLayout 方法Pod/Classes/FMMosaicLayout.m第 55-132 行。它按 section 循环每个 section 内部依次执行 6 个步骤重置缓存 → 初始化列高 → 顶部inset Header → 逐个摆放cell(最短列) → 收尾剩余cell → Footer 底部inset步骤做什么核心方法①清空列高与布局属性缓存resetLayoutState②为每列建一个高度计数器初始为 0columnHeightsPerSection③把顶部内边距、Header 高度记入所有列growColumnHeightsBy:section:④逐格寻找最短列放下大/小单元格indexOfShortestColumnInSection:⑤处理缓冲区内落单的小单元格addSmallMosaicLayoutAttributesForIndexPath:⑥计入 Footer 与底部内边距addLayoutAttributesForSupplementaryViewOfKind:下面逐步拆解。第 1 步重置布局状态清空三块缓存每次布局计算开始前resetLayoutState第 193-202 行会把三块核心缓存全部置空columnHeightsPerSection每个 section 各列的累计高度cellLayoutAttributes所有单元格的布局属性字典supplementaryLayoutAttributesHeader/Footer 的布局属性字典这保证旋转屏幕、数据刷新等场景下计算永远从零开始不会残留旧位置。窗口尺寸变化时shouldInvalidateLayoutForBoundsChange:第 182-191 行会主动调用prepareLayout触发这套重算流程。第 2 步初始化列高二维数组——整个算法的心脏这是理解 FMMosaicLayout 布局计算的钥匙。库为每个 section 维护一个列高度数组第 206-224 行懒加载数组长度 该 section 的列数由 delegate 返回默认 2每个元素初始为 0代表这一列目前已占用的垂直空间之后每放下一个单元格就把它的高度 间距累加进对应列。这样哪列最短随时一目了然——它就是所有单元格的落点依据。第 3 步顶部内边距与 Header 先占位在摆放任何单元格之前先给所有列垫底第 65-75 行用growColumnHeightsBy:section:把 section 顶部 inset 加到每一列上计算 Header 的布局属性若 delegate 表示 Header 不覆盖内容再把Header 高度 间距累加到每一列growColumnHeightsBy:section:第 352-358 行就是遍历列高数组统一加值的小工具。这样做的好处是后续所有单元格的 Y 坐标计算只需要当前列高 section 起始偏移不必再关心 inset 和 Header 的细节。第 4 步核心算法——最短列策略逐个摆放单元格接下来进入 for 循环第 79-106 行逐个处理单元格。每处理一个单元格前都会重新计算一次最短列第 83 行注释明确要求每次都要重算因为前一格的落位已经改变了列高分布。大单元格直接落到最短列若 delegate 返回FMMosaicCellSizeBig单元格直接放入最短列计算 frame → 存入缓存 → 该列高度累加单元格高度 间距。整个过程只涉及一次列高更新。小单元格两个一组缓冲配对马赛克效果的秘诀小单元格不能单独落位——两个小格并排才刚好占满一列宽。库用一个容量为 2 的缓冲区smallMosaicCellIndexPathsBuffer来处理遇到小单元格先扔进缓冲区缓冲区满 2 个时一次性把这两个小格放进当前最短列X 坐标通过 bufferIndex 错开半个列宽第 253 行该列高度只累加一次小格高度 间距然后清空缓冲区这就是马赛克布局计算中最巧妙的设计小格永远成对出现视觉上如同拼图的半块砖与大格交错出参差错落的节奏感。第 5 步处理落单的小单元格缓冲区收尾如果某 section 的小单元格总数是奇数循环结束后缓冲区里会剩 1 个落单者第 109-118 行。处理方式是把它单独放入当前最短列只占半个列宽剩余空间留白——这恰好对应示例中部分 section 末尾出现的半空位属于有意保留的马赛克风格而非 bug。第 6 步Footer 与底部内边距收尾每个 section 的最后第 121-130 行计算 Footer 布局属性。若 delegate 表示 Footer 覆盖内容它的 Y 坐标会上移自身高度第 305-307 行叠放在最后一排单元格之上Footer 不覆盖时把 Footer 高度累加到所有列最后加上 section 底部 inset至此该 section 的列高数组已代表它的完整内容高度。下一个 section 的起始 Y 坐标由verticalOffsetForSection:第 339-350 行累加前面所有 section 的最高列高度得到——注意是最高列因为最矮列的空白会被计入 section 总高。关键坐标公式一个单元格的 frame 是怎么算出来的所有 frame 计算集中在mosaicCellRectWithSize:atIndexPath:inColumn:第 272-289 行拆解后只有 4 个公式量计算方式说明列宽内容宽 − 左右 inset − 总列间距÷ 列数columnWidthInSection:第 330-336 行大格边长 列宽正方形小格边长列宽 − 列间距÷ 2两个并排刚好一列X 坐标列序 ×列宽 列间距 左 inset小格再按 bufferIndex 偏移半个格宽Y 坐标section 垂直偏移 当前列高列高即这一列已用掉的空间可见每个单元格的位置完全由落在哪一列和该列当前高度两个量决定逻辑极其干净。滚动与重排布局结果如何被高效复用prepareLayout是一次性全量计算成果存进两块字典缓存后续滚动几乎零开销可视区查询layoutAttributesForElementsInRect:第 135-153 行遍历缓存只返回与屏幕矩形相交的布局属性整体内容尺寸collectionViewContentSize第 164-174 行 视图宽度 × 各 section 最高列高度之和数据增删或尺寸变化时只需让布局失效系统会重新走一遍 prepareLayout 全流程缓存自动刷新无需手动维护。源码文件路径速查 文件作用Pod/Classes/FMMosaicLayout.m布局计算核心实现prepareLayout、列高算法、坐标公式Pod/Classes/FMMosaicLayout.h头文件与FMMosaicLayoutDelegate协议定义Example/FMMosaicLayout/FMMosaicCollectionViewController.m完整示例3 个 section、大小格交替、Header/Footer 覆盖Example/FMMosaicLayout/FMMosaicCellView.m马赛克单元格视图Example/FMMosaicLayout/FMHeaderView.h/FMFooterView.h自定义 Header 与 Footer 视图FMMosaicLayout.podspecCocoaPods 组件描述总结记住这条主线FMMosaicLayout 的 prepareLayout 布局计算可以浓缩为一句话给每列装一个高度计数器谁矮就把格子放进谁小格必须凑够两个再落位。配合成对缓冲与最高列结算用最少的状态一个二维数组换来了瀑布流级别的马赛克排布效果——这也是它作为 UICollectionViewLayout 自定义布局方案值得学习的地方。【免费下载链接】FMMosaicLayoutA drop-in mosaic collection view layout with a focus on simple customizations.项目地址: https://gitcode.com/gh_mirrors/fm/FMMosaicLayout创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

GetQzonehistory:一键完整备份QQ空间历史说说,找回已经从空间里消失的旧动态记录

GetQzonehistory:一键完整备份QQ空间历史说说,找回已经从空间里消失的旧动态记录

GetQzonehistory:一键完整备份QQ空间历史说说,找回已经从空间里消失的旧动态记录 【免费下载链接】GetQzonehistory 获取QQ空间发布的历史说说 项目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory GetQzonehistory 是一款QQ空间说…

2026/8/22 14:58:14 阅读更多 →
AI智能体实战:基于循环工程与Harness工程的开发部署指南

AI智能体实战:基于循环工程与Harness工程的开发部署指南

这次我们来看一个关于 AI 智能体架构的实战项目。它不是某个单一的模型或工具,而是一套围绕“循环工程”与“Harness 工程”理念构建的 AI 智能体开发框架与实践体系。简单来说,它旨在解决如何让 AI 智能体(Agent)在真实、复杂的业…

2026/8/22 14:58:14 阅读更多 →
从零构建深度学习数据流水线:Dataset、DataLoader与参数调优实战

从零构建深度学习数据流水线:Dataset、DataLoader与参数调优实战

刚拿到自己的数据集,准备跑通第一个深度学习模型时,很多人会陷入一种“教科书式”的迷茫。你照着教程,用MNIST、CIFAR-10这些标准数据集,代码一行行敲下去,结果顺利得出。但当你满怀信心地把自己的图片、文本或表格数据…

2026/8/22 14:58:13 阅读更多 →

最新新闻

论文AI率过高怎么办?2026年12款免费降AI率工具实测指南

论文AI率过高怎么办?2026年12款免费降AI率工具实测指南

现在毕业论文答辩前,“AI率超标”已经彻底取代“查重率过高”,成了同学们的头号难题!不少同学只是用AI润色了摘要和结论,AI率直接飙升到离谱,纯手动修改根本不管用——这说明AIGC检测系统抓的不是个别词语,…

2026/8/23 23:59:54 阅读更多 →
Marketch:从Sketch画板直接量取CSS

Marketch:从Sketch画板直接量取CSS

Marketch:从Sketch画板直接量取CSS 【免费下载链接】marketch Marketch is a Sketch 3 plug-in for automatically generating html page that can measure and get CSS styles on it. 项目地址: https://gitcode.com/gh_mirrors/ma/marketch 设计稿交付还在…

2026/8/23 23:59:54 阅读更多 →
如何在ThinkPad X390上安装macOS:OpenCore EFI完整指南

如何在ThinkPad X390上安装macOS:OpenCore EFI完整指南

如何在ThinkPad X390上安装macOS:OpenCore EFI完整指南 【免费下载链接】ThinkpadX390-Opencore-EFI macOS Catalina & Big Sur & Monterey on ThinkPad X390 (Hackintosh) 项目地址: https://gitcode.com/gh_mirrors/th/ThinkpadX390-Opencore-EFI …

2026/8/23 23:59:54 阅读更多 →
WechatHook 终极指南:5大核心能力详解,3分钟看懂微信自动化

WechatHook 终极指南:5大核心能力详解,3分钟看懂微信自动化

WechatHook 终极指南:5大核心能力详解,3分钟看懂微信自动化 【免费下载链接】WechatHook Enjoy hooking wechat by Xposed....Accessibility...and so on... 项目地址: https://gitcode.com/gh_mirrors/we/WechatHook WechatHook 是一个基于 Xpos…

2026/8/23 23:59:54 阅读更多 →
OpenModScan:免费跨平台 Modbus 主站调试工具,让现场通讯验证一键搞定

OpenModScan:免费跨平台 Modbus 主站调试工具,让现场通讯验证一键搞定

OpenModScan:免费跨平台 Modbus 主站调试工具,让现场通讯验证一键搞定 【免费下载链接】OpenModScan Open ModScan is a Free Modbus Master (Client) Utility 项目地址: https://gitcode.com/gh_mirrors/op/OpenModScan OpenModScan 是一款开源免…

2026/8/23 23:59:54 阅读更多 →
Gin-JWT认证与授权方案从Token到RBAC权限控制

Gin-JWT认证与授权方案从Token到RBAC权限控制

Gin-JWT认证与授权方案从Token到RBAC权限控制 文章导语 JWT(JSON Web Token)是现代Web服务的身份认证标准。在Gin框架中集成JWT看似简单,但涉及Token刷新、黑名单、多设备登录、RBAC权限控制等实际需求时,就需要更完善的设计。本文…

2026/8/23 23:57:54 阅读更多 →

日新闻

周新闻

[光学原理与应用-521]:对光的错误理解与纠偏

[光学原理与应用-521]:对光的错误理解与纠偏

首先光是一种能量的载体和形态,宏观上观察到的光是由无数个微观的光量子组成的,每个光子在产生的瞬间,其在真空的空间中以确定不变的速度沿着一个初始的方向一直向前,在微观层面,每个光量子的运动轨迹是以波函数所展现…

2026/8/24 0:06:02 阅读更多 →
SIP通话转接原理与REFER方法实战解析

SIP通话转接原理与REFER方法实战解析

1. 通话转接不是“挂断再拨号”,而是SIP会话的动态重定向你有没有遇到过这样的场景:客服坐席A正在和客户通电话,突然需要把这通对话无缝转给专家坐席B,客户完全感知不到中间的断连——既没听到忙音,也没被要求重新拨号…

2026/8/24 0:20:20 阅读更多 →
Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

1. 为什么选择Kolla-ansible来部署单节点OpenStack?如果你正在寻找一种能把OpenStack从“概念”快速变成“可用的实验环境”的方法,那么Kolla-ansible几乎是当前最主流、最省心的选择。我见过太多人卡在手动编译依赖、配置服务、处理版本冲突的泥潭里&am…

2026/8/24 0:14:11 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/23 18:47:06 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/23 12:10:44 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/22 3:22:48 阅读更多 →