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

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

(0)

相关推荐

  • IOS展开三级列表效果示例

    效果图如下: #import <UIKit/UIKit.h> @interface AppDelegate : UIResponder <UIApplicationDelegate> @property (strong, nonatomic) UIWindow *window; @end #import "AppDelegate.h" #import "RootViewController.h" @interface AppDelegate

  • 讲解iOS开发中UITableView列表设计的基本要点

    一.UITableView简单介绍 1.tableView是一个用户可以滚动的多行单列列表,在表视图中,每一行都是一个UITableViewCell对象,表视图有两种风格可选 复制代码 代码如下: typedef NS_ENUM(NSInteger, UITableViewStyle) {     UITableViewStylePlain,                  // regular table view     UITableViewStyleGrouped           

  • 使用UItableview在iOS应用开发中实现好友列表功能

    基本实现 一.项目结构和plist文件 二.实现代码 1.说明: 主控制器直接继承UITableViewController 复制代码 代码如下: //  YYViewController.h //  02-QQ好友列表(基本数据的加载) // //  Created by apple on 14-5-31. //  Copyright (c) 2014年 itcase. All rights reserved. // #import <UIKit/UIKit.h> @interface YY

  • IOS实现简易版的QQ下拉列表

    下面我们通过实例代码来一步步看怎么实现, 首先建立了两个模型类, 一个Friend, 一个FriendGroup类. 数据源用的本地的一个plist文件. plist文件中包含了FriendGroup的name,friends数组等属性. Friend.h 示例代码 #import <Foundation/Foundation.h> @interface Friend : NSObject @property (nonatomic, copy) NSString *name; @end Fri

  • ios基于UITableViewController实现列表

    实现效果图如下: News.h #import <Foundation/Foundation.h> @interface News : NSObject @property (nonatomic, strong) NSString *title; @property (nonatomic) NSUInteger count; @property (nonatomic, strong) NSString *imageName; + (NSArray *)demoData; @end<str

  • Android实现三级联动下拉框 下拉列表spinner的实例代码

    主要实现办法:动态加载各级下拉值的适配器 在监听本级下拉框,当本级下拉框的选中值改变时,随之修改下级的适配器的绑定值              XML布局: 复制代码 代码如下: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_w

  • iOS实现列表与网格两种视图的相互切换

    下图为京东商城的截图 很多人看到这个,第一眼想到的是用TableView和CollectionView来做切换,笔者刚开始也是认为这么做,后来发现还有一个非常的简单方法,就可以实现这个功能. 实现代码 1.首先创建一个CollectionView. - (UICollectionView *)collectionView { if (!_collectionView) { UICollectionViewFlowLayout *flowlayout = [[UICollectionViewFlo

  • IOS实现展开二级列表效果

    先来看看效果图 用法(类似UITableView) 初始化XDMultTableView #import "XDMultTableView.h" ... @property(nonatomic, readwrite, strong)XDMultTableView *tableView; _tableView = [[XDMultTableView alloc] initWithFrame:CGRectMake(0, 64, self.view.frame.size.width, sel

  • iOS功能实现之列表的横向刷新加载

    库命名为PSRefresh,支持UIScrollView及所有UIScrollView的子类控件,UITableView(横向的tableVIew)及UICollectionView等皆可. 支持自定义文字,支持自定义gif图,可设置是否为最后一页. 本文一共提供了三种样式,分别是普通样式.gif加载样式(带有状态label).git加载样式(不带有状态label). Demo展示如下: 使用时导入 "UIScrollView+PSRefresh.h" 文件即可,文件中提供的属性及接口

  • iOS多级列表实现代码

    在项目开发中,层级列表经常遇到,简单点的二级列表利用UITableView的Header就可以实现,再简单点的三级列表通过对Cell高度进行调整也可以实现三级列表的效果.但遇到多级列表,尤其是层次不明的动态列表就比较麻烦了. 原理 层级列表和树形结构比较类似,不过不是二叉树,而是多叉树.每个节点只需要拥有指向父节点和子节点的两个指针,就能形成一颗树.我们将多级列表中每一级对象看作一个node,node拥有两个属性,分别为父节点和子节点的ID. 每棵树有个一个虚拟的root节点,它的ID为root

  • Android 绘制多级树形选择列表实例代码

    一.概述 前段时间有个项目的需要在Android端显示一个复选的多层树形控件,主要展示一个公司的组织架构,类似总部下面有各个部门,部门之下是组和员工等.另外需要加上展开与回收部门详情.关闭部分已开展的布局.勾选等功能. 效果图如下: 二.思路分析 毫无疑问,对于这种数据可能达到几千几万行的列表视图,我们需要选择recyclerview等具有回收item功能的控件,因此Item的状态保持放在Model中而不是View中. 由于原始数据是树形结构的,我们需要先将树形结构转换为列表数据,类似根结点 -

  • android开发仿ios的UIScrollView实例代码

    今天重新装了编译器,结果崩无极限,真是日了狗了了.刚刚才知道问题在哪边. 好了,说正事,对于ios开发我没接触,不是很了解,百度了半天,差不多就是UIScrollView的把.如果不对,请指证.具体什么效果呢,我刚才拿朋友的iphone手机看了下,iphone的设置界面,第一个列表往下拉可以继续滚,上拉同理.不过android好像没有自带的这种情况. 我把这种效果称为滚无极限的scollview. 下面就来上源码: 首先,最最最重要的就是判断当前视图是否为空,你空视图滚不滚好像没啥区别,除了an

  • Android实现多级列表中的新建功能

    本文实例为大家分享了Android实现多级列表中的新建功能,供大家参考,具体内容如下 多级列表的页面实现比较简单,所以把新建的功能拿出来了. 窗口代码 /** * 新建一个第一级列表的条目 * 1.选择图片和附件都用Intent.ACTION_GET_CONTENT实现 * 2.打开文件用Intent.ACTION_VIEW实现 * 3.回传的URI需要转化成真实路径 * 4.提交数据之后需要刷新列表 */ public class SectionNewActivity extends AppC

  • iOS实现列表折叠效果

    本文实例为大家分享了iOS实现列表折叠效果的具体代码,供大家参考,具体内容如下 实现列表折叠效果其实比较简单,点击列表头部的时候,把返回列表行数设为 0,就是收起列表:再次点击列表头部,显示列表的行数,就展开了列表. #import "TableDownUpVC.h" #import "TableViewCell_TableSelect.h" @interface TableDownUpVC () { NSMutableDictionary *dicSelet; N

  • C/C++ Qt 数据库与ComBox实现多级联动示例代码

    Qt中的SQL数据库组件可以与ComBox组件形成多级联动效果,在日常开发中多级联动效果应用非常广泛,例如当我们选择指定用户时,我们让其在另一个ComBox组件中列举出该用户所维护的主机列表,又或者当用户选择省份时,自动列举出该省份下面的城市列表等. 今天给大家分享二级ComBox菜单如何与数据库形成联动,在进行联动之前需要创建两张表,表结构内容介绍如下: User表:存储指定用户的ID号与用户名 UserAddressList表:与User表中的用户名相关联,存储该用户所管理的主机列表信息 v

  • VUE递归树形实现多级列表

    本文实例为大家分享了VUE递归树形实现多级列表,供大家参考,具体内容如下 什么是递归? 简单来说就是在组件中内使用组件本身. 为什么要用递归? 如果出现很多下拉菜单,同级,分级数据,层级混杂,可以使用v-for的嵌套循环不就完事了.对,没毛病这样的话也可以做,但是如果数据又多加了[很多]级分类呢:使用v-for也能实现,但是代码可能会比较杂或混乱!也不适合后期的维护,这个时候呢,我们就可以使用我们所说道的[递归组件 ]了,使用递归组件,无论你的数据怎么增加我们都不用改动我们的代码. 先看效果:

  • jQuery垂直多级导航菜单代码分享

    这是一款基于jquery实现的垂直导航菜单特效代码,总共有三级,实现效果简单大方,最后一级还可以进行图片展示说明,是一款非常实用的导航菜单特效源码. 效果演示 源码下载 为大家分享的jQuery垂直多级导航菜单代码如下 <head> <title>jQuery垂直多级导航菜单代码</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"

  • js实现无限级树形导航列表效果代码

    本文实例讲述了js实现无限级树形导航列表效果代码.分享给大家供大家参考.具体如下: 这是一款js实现无限级树形下拉导航菜单,简洁实用,用到一个已封装好的JS类,有用的大家借鉴一下. 运行效果截图如下: 在线演示地址如下: http://demo.jb51.net/js/2015/js-unlimit-tree-style-nav-list-codes/ 具体代码如下: <meta http-equiv="Content-Type" content="text/html;

  • JS实现带有抽屉效果的产品类网站多级导航菜单代码

    本文实例讲述了JS实现带有抽屉效果的产品类网站多级导航菜单代码.分享给大家供大家参考.具体如下: 这是一款像抽屉一样的菜单,多用在产品网站,比如IT产品网站的分类导航上,菜单结构清淅,样式新颖,设计美观,主要是运用JavaScript技术实现,用CSS配合实现菜单背景的构建,总体来说,是学习Js多级分类菜单的好范例. 运行效果截图如下: 在线演示地址如下: http://demo.jb51.net/js/2015/js-ct-style-product-web-nav-menu-codes/ 具

随机推荐