说在前面:
这个需求其实已经做了好久了, 中间一直想写篇简书的, 也拖拖拉拉就晃到了现在, 刚拿到这个需求, 之前都没有做过, 虽然只是数据展示, 但又有展开数据, 刷新数据, 之间的逻辑之前也是没想过, 就在网上查找了些资料, 很多, 但往往跟自己的需求出入有点大, 下面我说说自己的做法......
我这里以四级树杈结构为例:
这个需求的两个必要点
- 1 . 数据模型解析并保存方式
- 2 . 点击展开层级及数据刷新展示逻辑
数据模型解析并保存方式
- 先创建四种不同的 cell, 不同的数据模型
-
请求数据成功后, 进行数据转模型
WEAKSELF; [KRequestCenter requestDataWithURL:StockOut Parameters:para Method:@"POST" AuthorizationToken:YES TimeoutInterval:10 ParameterPrefix:NO Progress:nil withSuccessBlock:^(id response) { NSLog(@"akj: %@", response); if ([response[@"code"]intValue] == 200) { // 当返回值为 200 时, 请求成功 NSArray *listVoDataArr = response[@"data"][@"listVo"]; // 这是总的数组 // 循环遍历数组, 数据解析成模型 for (NSDictionary *dic in listVoDataArr) { LevelFirstModel *model = [[LevelFirstModel alloc]init]; [model2 setValuesForKeysWithDictionary:dic]; [_levelFirstArrM addObject:model]; } weakSelf.totalArrM = [NSMutableArray arrayWithArray:arrM]; dispatch_async(dispatch_get_main_queue(), ^{ [weakSelf.tableView reloadData]; }); } } withFailedBlock:^(NSError *error) { NSLog(@"asdfkj: %@", error); }];
在模型 .m 文件中, 对第二层数据进行模型解析
// 这个方法用于运行时赋值数据时, 找不到对应的 key 而执行的方法
- (void)setValue:(id)value forUndefinedKey:(NSString *)key
{
// list 这个 key 是假定后台返回的第二层数据数组, 放到这个方法, 传递到第二层模型解析数据
if ([key isEqualToString:@"list"]) { // 数组
self.listArrM = [NSMutableArray array];
// value 这个就是模型中找不到的 key 对应的值, 也就是第二层数据数组
for (NSDictionary *dic in value) {
// 数据转模型, 用数组保存
LevelSecondModel *model = [[LevelSecondModel alloc]init];
[model setValuesForKeysWithDictionary:dic];
[self.listArrM addObject:model];
}
self.level = 1; // 所处层级
self.isExpand = NO; // 默认不展开
}
}
cell点击展开层级及数据刷新展示逻辑
// MARK: - 点击 cell 加载展开数据
- (void)reloadDataForDisplayArrayChangeAt:(NSInteger)row {
NSMutableArray *tmp = [[NSMutableArray alloc]init];
NSInteger cnt = 0;
for (LevelFirstModel *node in _levelFirstArrM) {
[tmp addObject:node];
if (cnt == row) {
node.isExpand = !node.isExpand;
}
++cnt;
if (node.isExpand) {
for (LevelSecondModel *node2 in node.listArrM) {
[tmp addObject:node2];
if (cnt == row) {
node2.isExpand = !node2.isExpand;
}
++cnt;
if (node2.isExpand) {
for (LevelThirdModel *node3 in node2.listArrM) {
[tmp addObject:node3];
if (cnt == row) {
node3.isExpand = !node3.isExpand;
}
++cnt;
if (node3.isExpand) {
for (LevelForthModel *node4 in node3.listArrM) {
[tmp addObject:node4];
++cnt;
}
}
}
}
}
}
}
self.totalArrM = [NSMutableArray arrayWithArray:tmp];
[self.tableView reloadData];
}
具体的 demo 下载地址: https://gitee.com/LuckyChen73/MultiLevelMenuDemo
demo 中解决了展开列表数据错乱, 和复用的问题.
这个 demo 由于数据请求涉及到公司信息, 故运行没有数据展示, 但读者根据步骤做还是没有大问题的, 我一直在想怎么解决 由于导入类文件过多而导致耦合性太强的问题, 有idea 的可以在下方留言, 我尝试改进......
最后谢谢大家阅读, 希望能对大家起到一点帮助!