代码地址如下:
http://www.demodashi.com/demo/15006.html

效果预览

一、需求

TableView多级列表:分级展开或合并,逐级获取并展示其子级数据,可以设置最大的层级数,支持多选、单选、取消选择。

二、思路

由需求和示意图可知,这些数据元素之间存在着一对多关系,很符合 数据结构与算法 – 树形结构 的特征。那么,我们就用树形结构中的结点(Node)来作为存储和关联数据的模型(NodeModel)。


//每个结点信息,采用的是树状结构模型关于树状结构不了解的可以看看我的这篇文章 https://www.jianshu.com/p/c545c93f2585@interface SLNodeModel : NSObject@property (nonatomic, strong) NSString *parentID; // 父结点ID 即当前结点所属的的父结点ID@property (nonatomic, strong) NSString *childrenID; //子结点ID 即当前结点的ID@property (nonatomic, strong) NSString *name; //结点名字@property (nonatomic, assign) int level; // 结点层级 从1开始@property (nonatomic, assign) BOOL leaf;  // 树叶(Leaf) If YES:此结点下边没有结点咯;@property (nonatomic, assign) BOOL root;  // 树根((Root) If YES: parentID = nil@property (nonatomic, assign) BOOL expand; // 是否展开@property (nonatomic, assign) BOOL selected; // 是否选中@end

三、实现

层级状态: 根据传入的层级数来调整层级UI状态。

展开或合并: 通过插入或删除cell的方式来实现。(示例中的数据都是假数据,随机生成的。)

插入和删除的位置以及范围可通过点击的结点的位置、层级、子结点ID(当前结点ID)与子结点的层级或父节点相比较来确定。可以的话,做一下缓存处理,优化不分大小,从点滴做起


/**获取并展开父结点的子结点数组 数量随机产生@param level 父结点的层级@param indexPath 父结点所在的位置*/
- (void)expandChildrenNodesLevel:(int)level atIndexPath:(NSIndexPath *)indexPath {NSMutableArray * insertNodeRows = [NSMutableArray array];int insertLocation = (int)indexPath.row + 1;for (int i = 0; i < arc4random()%9; i++) {SLNodeModel * node = [[SLNodeModel alloc] init];node.parentID = @"";node.childrenID = @"";node.level = level + 1;node.name = [NSString stringWithFormat:@"第%d级结点",node.level];node.leaf = (node.level < MaxLevel) ? NO : YES;node.root = NO;node.expand = NO;node.selected = NO;[self.dataSource insertObject:node atIndex:insertLocation + i];[insertNodeRows addObject:[NSIndexPath indexPathForRow:insertLocation + i inSection:0]];}//插入cell[self.tableView beginUpdates];[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithArray:insertNodeRows] withRowAnimation:UITableViewRowAnimationNone];[self.tableView endUpdates];//更新新插入的元素之后的所有cell的cellIndexPathNSMutableArray * reloadRows = [NSMutableArray array];int reloadLocation = insertLocation + (int)insertNodeRows.count;for (int i = reloadLocation; i < self.dataSource.count; i++) {[reloadRows addObject:[NSIndexPath indexPathForRow:i inSection:0]];}[self.tableView reloadRowsAtIndexPaths:reloadRows withRowAnimation:UITableViewRowAnimationNone];
}/**获取并隐藏父结点的子结点数组@param level 父结点的层级@param indexPath 父结点所在的位置*/
- (void)hiddenChildrenNodesLevel:(int)level atIndexPath:(NSIndexPath *)indexPath {NSMutableArray * deleteNodeRows = [NSMutableArray array];int length = 0;int deleteLocation = (int)indexPath.row + 1;for (int i = deleteLocation; i < self.dataSource.count; i++) {SLNodeModel * node = self.dataSource[i];if (node.level > level) {[deleteNodeRows addObject:[NSIndexPath indexPathForRow:i inSection:0]];length++;}else{break;}}[self.dataSource removeObjectsInRange:NSMakeRange(deleteLocation, length)];[self.tableView beginUpdates];[self.tableView deleteRowsAtIndexPaths:deleteNodeRows withRowAnimation:UITableViewRowAnimationNone];[self.tableView endUpdates];//更新删除的元素之后的所有cell的cellIndexPathNSMutableArray * reloadRows = [NSMutableArray array];int reloadLocation = deleteLocation;for (int i = reloadLocation; i < self.dataSource.count; i++) {[reloadRows addObject:[NSIndexPath indexPathForRow:i inSection:0]];}[self.tableView reloadRowsAtIndexPaths:reloadRows withRowAnimation:UITableViewRowAnimationNone];
}

选中: 会更新当前结点下所有子结点的选中状态。

选中的位置以及范围可通过点击的结点的位置、层级、子结点ID(当前结点ID)与子结点的层级或父节点相比较来确定。可以的话,做一下缓存处理,优化不分大小,从点滴做起


/**更新当前结点下所有子节点的选中状态@param level 选中的结点层级@param selected 是否选中@param indexPath 选中的结点位置*/
- (void)selectedChildrenNodes:(int)level selected:(BOOL)selected atIndexPath:(NSIndexPath *)indexPath {NSMutableArray * selectedNodeRows = [NSMutableArray array];int deleteLocation = (int)indexPath.row + 1;for (int i = deleteLocation; i < self.dataSource.count; i++) {SLNodeModel * node = self.dataSource[i];if (node.level > level) {node.selected = selected;[selectedNodeRows addObject:[NSIndexPath indexPathForRow:i inSection:0]];}else{break;}}[self.tableView reloadRowsAtIndexPaths:selectedNodeRows withRowAnimation:UITableViewRowAnimationNone];
}

四、项目结构

iOS TableView多级列表

代码地址如下:
http://www.demodashi.com/demo/15006.html

注:本文著作权归作者,由demo大师发表,拒绝转载,转载需要作者授权

iOS TableView多级列表相关推荐

  1. iOS TableView实现QQ好友列表(二)

    上节:iOS TableView实现QQ好友列表(一) http://blog.csdn.net/lwjok2007/article/details/46534123 上一节实现了简单的好友列表,但是 ...

  2. iOS TableView实现QQ好友列表(三)

    上节我们讲到如何展示好友信息 iOS TableView实现QQ好友列表(二) http://blog.csdn.net/lwjok2007/article/details/46549111 接下来我 ...

  3. iOS TableView 使用详解

     IOS TableView 详解 一.建立 UITableView DataTable = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, ...

  4. ios学习 准备列表

    2019独角兽企业重金招聘Python工程师标准>>> Skip to content This repository Pull requests Issues Gist Watch ...

  5. iOS tableview的常用delegate和dataSource执行顺序

    在这次项目中遇到了一个特别奇葩的问题:表视图创建的cell在7以上的系统能正常运行显示,在模拟器上就不能正常实现......为解决这个问题,纠结了好久...... 对在7系统上不显示的猜测: 用mas ...

  6. word2010多级列表编号变成黑块的解决方案

    为什么80%的码农都做不了架构师?>>>    1.在文档最后键入多行文字,分别设置为和多级列表关联的样式.(依然显示黑块) 2.选择新键入的这部面文字,先选择多级列表的无,然后再选 ...

  7. ios tableview分组间距

    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { // ios ta ...

  8. word报错:题注或页码中不含章节编号。请使用“开始”选项卡上的“多级列表”按钮,然后选择链接到标题样式的编号方案(无法添加题注)

    这破问题还真不好解决.... 看了这个视频:WORD教学五(论文排版之论文中的图表跟随章节插入题注) 貌似知道怎么弄了..这样操作: 选择标题,然后点击多级列表 --> 定义新的多级列表 然后在 ...

  9. word里的多级列表和项目编号是什么区别?

    numbering:主要用于创建同级编号,对于正文内并列关系的段落增加编号. multilevel list:主要用于创建多层编号,还能和标题之类绑定,为不同层级的标题加编号.这个用的比较多,还能创建 ...

最新文章

  1. python3 byte_「Python3学习笔记」读书笔记—字节数组
  2. Linux非阻塞IO(二)网络编程中非阻塞IO与IO复用模型结合
  3. DbExpressionBinding requires an input expression with a collection ResultType. 参数名: input
  4. TensorFlow 教程 --进阶指南--3.4数据读取
  5. SQA计划和系统测试规程
  6. python3.X出现关于模块(i18n)的不能使用的解决方法
  7. UTI iPhone支持依文件后缀名打开应用
  8. appium+python 多设备并行执行脚本【转】
  9. html在线预览wordexcel文档,直接在线预览Word、Excel、TXT文件之ASP.NET
  10. 万人拆盲盒,比特小鹿“2周年庆”云托管新团掀高潮
  11. 易基因 | 表观技术:单细胞及微量细胞全基因组重亚硫酸盐甲基化测序(scWGBS)
  12. 关于看算法导论不懂的时候的思考
  13. 2022长三角数学建模A题
  14. 行业洞察系列之《事件管理的 5 个阶段及其改进建议》
  15. matlab randn 范围,如何用matlab编写randn函数?
  16. Android 圆形头像控件CircleImageView
  17. SiTime硅晶振MEMS谐振子制作工艺详解
  18. jedis异常:Could not get a resource from the pool
  19. 2019.06.28(day01)_java大数据课程体系
  20. 常用数据库选型!你做对了吗?

热门文章

  1. java集合对象排序_java ArrayList集合中的某个对象属性进行排序的实现代码
  2. 1004.ubuntu16.04 安装protobuf
  3. 基于java洗浴中心管理系统_Java小白也能听懂的线程池的内部原理:老王的洗浴中心...
  4. 【C语言】找到兼职了心情紧张!
  5. mysql 字符串取前缀_mysql截取字符串的函数总结
  6. STM32 I2C通信(读写eeprom)
  7. libevent源码深度剖析三
  8. js java传参乱码_【技术贴】解决前台js传参中文乱码
  9. python函数的嵌套和递归_Python通过递归函数输出嵌套列表元素
  10. 【LeetCode】剑指 Offer 59 - I. 滑动窗口的最大值