首页 > 其他分享 >iOS TableView多级列表

iOS TableView多级列表

时间:2023-06-02 13:32:05浏览次数:36  
标签:node 结点 TableView level int self 多级 iOS NSMutableArray

效果预览

一、需求

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的cellIndexPath
    NSMutableArray * 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的cellIndexPath
    NSMutableArray * 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多级列表_iOS




标签:node,结点,TableView,level,int,self,多级,iOS,NSMutableArray
From: https://blog.51cto.com/u_7583030/6401898

相关文章

  • iOS企业签名掉签,iOS企业签名掉签了怎么办?103.107.190.x
    不能上架到AppStore的iOS应用,几乎每一个开发者的选择都是通过iOS签名这种内测渠道来完成APP的上架任务,最常用的就是企业签名、超级签名以及TF上架,其中最受欢迎的当属于企业签名了。不过企业签名会出现掉签的现象,那么企业签名掉签了该如何处理呢?今天我就来分享下关于签名掉签的原......
  • AI智能安监平台EasyCVR多级分组展开按钮无法操作的问题优化
    EasyCVR基于云边端协同,可支持海量视频的轻量化接入与汇聚管理。平台既具备传统安防视频监控的能力,比如:视频监控直播、云端录像、云存储、录像检索与回看、智能告警、平台级联、云台控制、语音对讲等,也能接入AI智能分析的能力,包括人脸检测、车辆检测、烟火检测、安全帽检测、区域入......
  • mock拦截axios请求,以及axios请求拦截设置token
     直接上源码:<!DOCTYPEhtml><html><head><metacharset="UTF-8"><title>mock拦截axios请求</title></head><body><!--本地npm安装mock和axios--><!--<scriptsrc="../node_modu......
  • ShareSDK iOS端合规指南
    2021年5月1日起,由国家互联网信息办公室、工业和信息化部、公安部、国家市场监督管理总局联合制定了《常见类型移动互联网应用程序必要个人信息范围规定》(简称“App必要个人信息范围规定”)已正式施行。“App必要个人信息范围规定”不仅明确常见39种类型的App必要个人信息范围,而且明......
  • BFT最前线 | iOS版ChatGPT周下载突破50万人次;英伟达市值突破万亿美元创造芯片公司历史
    原创|文BFT机器人AI视界TECHNOLOGYNEWS01联合国教育部聚焦生成式AI联合国科教文组织提出发展路线图近日,为应对生成式人工智能技术的迅速发展,联合国教科文组织就此议题召开了首次全球教育部长会议。40多位部长分享了将这些工具融入教育的政策方法和规划,并交换了意见。会议期间,教......
  • iOS-高仿通讯录之商品索引排序搜索
    概述TableView添加右侧索引,将数据按照索引分组排序,并添加搜索功能且在搜索界面复用当前页面.详细项目中像一些商品搜索类界面,TableView添加右侧索引的使用越来越多,的确用户体验提高了许多.一、主要思路大致思路:1.添加并设置右侧索引2.自定义汉字转化成拼......
  • iOS仿支付宝芝麻信用仪表盘效果
    概述自定义View之高仿支付宝芝麻信用分数仪表盘动画效果详细仿支付宝芝麻信用仪表盘效果一、主要思路1.圆环上绿点的旋转2.分数值及提示语的变化3.背景色的变化二、程序实现一.自定义ZLDashboardView仪表盘文件:根据跃动数字,确定百分比,现在的跳动数字---->......
  • iOS蓝牙BLE4.0通信功能
    概述iOS蓝牙BLE4.0通信功能,最近刚学的苹果,为了实现蓝牙门锁的项目,找了一天学习了下蓝牙的原理,亲手测试了一次蓝牙的通信功能,结果成功了,那么就把我学习的东西分享一下。详细一、蓝牙常见名称和缩写BLE:(Bluetoothlowenergy)蓝牙4.0设备因为低耗电BLE:(Bluetoothlow......
  • iOS- 快速实现展示布局
    概述比较有规律的页面,快速实现展示布局,提高开发效率.详细看到这个界面,是不是觉得不像那种比较有规律的,可以用单独tableViewCell或者xib来实现方便些的,现在我直接在C里快速实现展示布局.一、程序实现先看布局,可以分成两个分区:在数据源方法里去处理......
  • 如何使用TableView展示表格数据
    如何使用TableView展示表格数据TableView可以展示一个行列二维表格。表格由表头和记录组成。表头由若干TableColumn组成。通过定义TableView的代码:TableView<Student>studentTableView;可以看出,记录的数据结构就是其模板参数。我们可以把Student的getXxx方法映射......