热门标签 | HotTags
当前位置:  开发笔记 > 开发工具 > 正文

iOS多级列表实现代码

这篇文章主要为大家详细介绍了iOS多级列表实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

在项目开发中,层级列表经常遇到,简单点的二级列表利用UITableView的Header就可以实现,再简单点的三级列表通过对Cell高度进行调整也可以实现三级列表的效果。但遇到多级列表,尤其是层次不明的动态列表就比较麻烦了。

原理

层级列表和树形结构比较类似,不过不是二叉树,而是多叉树。每个节点只需要拥有指向父节点和子节点的两个指针,就能形成一颗树。我们将多级列表中每一级对象看作一个node,node拥有两个属性,分别为父节点和子节点的ID。

每棵树有个一个虚拟的root节点,它的ID为rootID,所有节点中凡是父节点ID为rootID的便是第一级,对应树结构中的depth(深度)。这样每一个node对象就都拥有了parentID和childrenID, childrenID为node对象的ID。

我们可以通过rootID查出第一级node,再根据第一级node的childrenID查出下一级,依次类推,确定所有节点的父子关系。同时也可以确定叶子节点和第一级节点,也可称

为根节点。

效果图

1.一般多级列表

2.记录节点历史状态的列表

思路

1.首先根据 rootID 获取所有第一级节点,并放入UITableView的数据源 dataSourceArr 中,展示初始化列表

2. 展开: 点击节点cell,根据 childrenID 查找下一级nodes,并插入到 dataSourceArr 中currentNode的后面,刷新展示

3. 收拢: 点击以打开节点cell,从 dataSourceArr 的CurrentIndex+1开始,如果该节点的level小于currentNode的level,则移除node,否则停止刷新列表。

4.点击cell为叶子节点则不响应展开或收拢操作,并把节点信息通过返回。

dataSourceArr中是这样的一种符合树层级结构的顺序:

定义节点对象

遇到问题

1.局部刷新的问题

每次展开或收拢以后刷新列表,一开始采用

代码如下:
- (void)reloadSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation

但会导致节目有整体闪烁的效果,体验不好。最后考虑采用局部刷新 insertRowsAtIndexPaths 和 deleteRowsAtIndexPaths 。

但在刷新中会报错

* Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'attempt to delete row 2 from section 0 which only contains 2 rows before the update'

推测原因是 current Cell在刷新时的numberOfRowsInSection和刷新insert or del的cell时numberOfRowsInSection不一致导致 。然后尝试current cell和其他cell分别刷新,完美刷新。

[_reloadArray removeAllObjects];
 [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];

 if (currentNode.isExpand) {
  //expand
  [self expandNodesForParentID:currentNode.childrenID insertIndex:indexPath.row];
  [tableView insertRowsAtIndexPaths:_reloadArray withRowAnimation:UITableViewRowAnimationNone];
 }else{
  //fold
  [self foldNodesForLevel:currentNode.level currentIndex:indexPath.row];
   [tableView deleteRowsAtIndexPaths:_reloadArray withRowAnimation:UITableViewRowAnimationNone];
 }

2.怎么保存节点历史状态

当文件级层比较多时,有时希望能关掉层级后再打开时还能保留子层级的打开状态。我们可以会给每一个node一个是否展开的属性,当fold时只修改currentNode的expand属性,expand时对子节点序isexpand=YES的进行遍历插入。

//expand
- (NSUInteger)expandNodesForParentID:(NSString*)parentID insertIndex:(NSUInteger)insertIndex{

 for (int i = 0 ; i<_nodes.count;i++) {
  YKNodeModel *node = _nodes[i];
  if ([node.parentID isEqualToString:parentID]) {
   if (!self.isPreservation) {
    node.expand = NO;
   }
   insertIndex++;
   [_tempNodes insertObject:node atIndex:insertIndex];
   [_reloadArray addObject:[NSIndexPath indexPathForRow:insertIndex inSection:0]];//need reload nodes

   if (node.isExpand) {
    insertIndex = [self expandNodesForParentID:node.childrenID insertIndex:insertIndex];
   }
  }
 }

 return insertIndex;
}

demo地址:
https://github.com/YangKa/YKMutableLevelTableView.git

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


推荐阅读
  • 本文旨在探讨Swift中的Closure与Objective-C中的Block之间的区别与联系,通过定义、使用方式以及外部变量捕获等方面的比较,帮助开发者更好地理解这两种机制的特点及应用场景。 ... [详细]
  • 汇总了2023年7月7日最新的网络安全新闻和技术更新,包括最新的漏洞披露、工具发布及安全事件。 ... [详细]
  • 深入理解iOS中的链式编程:以Masonry为例
    本文通过介绍Masonry这一轻量级布局框架,探讨链式编程在iOS开发中的应用。Masonry不仅简化了Auto Layout的使用,还提高了代码的可读性和维护性。 ... [详细]
  • WebBenchmark:强大的Web API性能测试工具
    本文介绍了一款名为WebBenchmark的Web API性能测试工具,该工具不仅支持HTTP和HTTPS服务的测试,还提供了丰富的功能来帮助开发者进行高效的性能评估。 ... [详细]
  • ArcBlock 发布 ABT 节点 1.0.31 版本更新
    2020年11月9日,ArcBlock 区块链基础平台发布了 ABT 节点开发平台的1.0.31版本更新,此次更新带来了多项功能增强与性能优化。 ... [详细]
  • 基于SSM框架的在线考试系统:随机组卷功能详解
    本文深入探讨了基于SSM(Spring, Spring MVC, MyBatis)框架构建的在线考试系统中,随机组卷功能的设计与实现方法。 ... [详细]
  • binlog2sql,你该知道的数据恢复工具
    binlog2sql,你该知道的数据恢复工具 ... [详细]
  • Python3爬虫入门:pyspider的基本使用[python爬虫入门]
    Python学习网有大量免费的Python入门教程,欢迎大家来学习。本文主要通过爬取去哪儿网的旅游攻略来给大家介绍pyspid ... [详细]
  • 在VSCode中配置ESP-IDF开发环境
    本文详细介绍如何在无需单独下载工具链的情况下,通过VSCode配置ESP-IDF开发环境,包括下载离线安装包和安装ESP-IDF插件,从而实现项目编译与烧录。 ... [详细]
  • 本文分享了作者在使用LaTeX过程中的几点心得,涵盖了从文档编辑、代码高亮、图形绘制到3D模型展示等多个方面的内容。适合希望深入了解LaTeX高级功能的用户。 ... [详细]
  • 本文将详细介绍Fuel CMS如何基于CodeIgniter框架构建,包括其单入口模式的实现方式及关键配置文件的作用。通过分析本地环境中的index.php和.htaccess文件,我们将更好地理解Fuel CMS的核心架构。 ... [详细]
  • 本文提供了一个详尽的前端开发资源列表,涵盖了从基础入门到高级应用的各个方面,包括HTML5、CSS3、JavaScript框架及库、移动开发、API接口、工具与插件等。 ... [详细]
  • 本文详细介绍如何在SSM(Spring + Spring MVC + MyBatis)框架中实现分页功能。包括分页的基本概念、数据准备、前端分页栏的设计与实现、后端分页逻辑的编写以及最终的测试步骤。 ... [详细]
  • 本文回顾了作者在求职阿里和腾讯实习生过程中,从最初的迷茫到最后成功获得Offer的心路历程。文中不仅分享了个人的面试经历,还提供了宝贵的面试准备建议和技巧。 ... [详细]
  • 在Android中实现黑客帝国风格的数字雨效果
    本文将详细介绍如何在Android平台上利用自定义View实现类似《黑客帝国》中的数字雨效果。通过实例代码,我们将探讨如何设置文字颜色、大小,以及如何控制数字下落的速度和间隔。 ... [详细]
author-avatar
疯务情堂
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有