FMMoveTableView实战解析:手把手构建多Section电影列表长按拖动排序Demo

📅 2026/8/26 16:35:26
FMMoveTableView实战解析:手把手构建多Section电影列表长按拖动排序Demo
FMMoveTableView实战解析手把手构建多Section电影列表长按拖动排序Demo【免费下载链接】FMMoveTableViewDiscontinued: Please use iOS 11s Drag Drop capability instead.项目地址: https://gitcode.com/gh_mirrors/fm/FMMoveTableViewFMMoveTableView是一个经典的 iOS 开源组件它是UITableView的子类让表格行可以通过长按 拖动完成拖拽排序且无需切换到编辑模式。本文将带你从零构建一个多 Section 电影列表的长按拖动排序 Demo两个分组Section展示 30 部老电影手指按住任意一行上下拖动即可跨分组调整顺序。⚠️重要提示该项目已停止维护Discontinued。作者建议新项目直接使用iOS 11 及以上系统原生的 Drag Drop能力。但作为理解拖动排序底层实现原理的范本这个 Demo 依然非常值得一读。一、先看效果多Section电影列表Demo长什么样Demo 的界面结构很简单却五脏俱全两个 Section每个 Section 包含 15 部 1926–1932 年的经典电影数据来自 Movies.plist每行三个属性片名、年份、行高50/60/70 交错方便观察拖动时的行高适配长按任意行该行生成带阴影的快照悬浮跟随手指松手后完成排序并更新数据模型。启动图同时是 Demo 的界面基调如下图所示二、项目结构速览核心代码只有4个文件模块作用FMFramework/核心组件仅 4 个文件FMMoveTable/可运行的 Demo 工程核心就 4 个文件全部可以手动拖进项目FMMoveTableView.h / FMMoveTableView.m表格视图负责手势、快照与自动滚动FMMoveTableViewCell.h / FMMoveTableViewCell.m单元格负责被拖动时清空内容。三、最快接入方法6步配置清单按照 README 的官方说明接入步骤如下iOS 9 及更早项目适用导入QuartzCore框架快照阴影效果需要把FMMoveTableView.(h/m)和FMMoveTableViewCell.(h/m)加入工程也可通过 CocoaPods 安装见 FMMoveTableView.podspec将你的UITableView子类改为继承FMMoveTableViewStoryboard 中把 Class 改掉即可见 MainStoryboard.storyboard;将UITableViewCell子类改为继承FMMoveTableViewCell让 ViewController 遵循FMMoveTableViewDataSource协议可选遵循FMMoveTableViewDelegate协议Demo 入口见 FMViewController.h必须实现moveTableView:moveRowFromIndexPath:toIndexPath:在松手后更新你的数据模型。四、长按拖动原理拆解手势→快照→自动滚动整个拖动的灵魂在 FMMoveTableView.m可以拆成三个关键环节1️⃣ 长按手势拦截视图创建时挂上一个UILongPressGestureRecognizer。手势开始前会先询问数据源这一行允许拖动吗canMoveRowAtIndexPath:不允许就直接不响应——这就是拖拽权限的第一道闸门。2️⃣ 生成悬浮快照Snapshot长按成立的瞬间代码对当前 Cell 截图加上半透明与阴影让它漂浮起来跟随手指原 Cell 内容则被清空prepareForMove方法见 FMMoveTableViewCell.m形成原位置让位的视觉效果。3️⃣ 边缘自动滚动Autoscroll拖动到列表顶部/底部 60% 行高范围内时会启动一个 60fps 的定时器自动滚动表格让你能把行拖到屏幕外的位置——长列表排序体验的关键就在这里。五、多Section排序的3个数据源陷阱拖动过程中数据源处于**脏状态**真实数据要等松手后才更新因此数据源里必须做三处适配Demo 里都有醒目的注释陷阱处理位置核心技巧行数对不上FMViewController.m目标 Section 行数 1起始 Section 行数 -1内容错位FMViewController.m用adaptedIndexPathForRowAtIndexPath:把 indexPath 换算回真实数据位置行高错位FMViewController.m计算行高前同样先换算 indexPath松手后的最终落位快照动画飞回目标位置 → 回调moveRowFromIndexPath:toIndexPath:→ 你在这里把电影对象从旧 Section 数组移除、插入新 Section 数组数据模型更新完毕。整个拖动中的实时换位由表格内部用deleteRows insertRows模拟FMMoveTableView.m。六、常用回调速查想限制拖动范围改这一个方法FMMoveTableView设计了 4 个与系统UITableView拖拽风格对齐的回调全部定义在 FMMoveTableView.h能不能动moveTableView:canMoveRowAtIndexPath:数据源即将移动moveTableView:willMoveRowAtIndexPath:委托能不能去某位置moveTableView:targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath:委托移动完成moveTableView:moveRowFromIndexPath:toIndexPath:数据源 实用技巧在第三个回调中如果sourceIndexPath.section与proposedDestinationIndexPath.section不同就返回sourceIndexPath即可禁止跨 Section 拖动把行锁定在本分组内排序FMViewController.m 中已写好注释好的示例代码。七、总结旧组件值得学新项目请用原生Drag Drop学原理FMMoveTableView 用不到 450 行代码完整演示了手势识别 → 快照跟随 → 模拟换位 → 边缘自动滚动 → 脏数据修正的全链路是学习拖拽排序的绝佳范本做新项目iOS 11 请直接使用系统 Drag DropUITableViewDragDelegate/UITableViewDropDelegate获得系统级流畅体验与无障碍支持维护老项目若最低支持版本低于 iOS 11FMMoveTableView 依然是长按拖动排序的可靠选择。希望这篇 FMMoveTableView 实战解析能帮你彻底读懂表格拖动排序的实现原理。【免费下载链接】FMMoveTableViewDiscontinued: Please use iOS 11s Drag Drop capability instead.项目地址: https://gitcode.com/gh_mirrors/fm/FMMoveTableView创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考