ios UITabelView实现树状解构的一种方法

     之前在自己的项目中,遇到了这样一需求,项目里有聊天的功能,需要自己管理好友列表,而且好友是属于有上下级的关系,所有就要做一个树状的UITabelView的结构.

首先说一下大概的思路:

1.根据我自己的项目来说,首先是请求接口,获得联系人列表数据,当然需要根据数据建立数据模型model,这个是我项目里的数据模型:

@interface ObjModel : NSObject

@property (nonatomic,copy)NSString * ID;//这个是该对象上一级的唯一标示ID

@property (nonatomic,copy)NSString * imCode;

@property (nonatomic,copy)NSString * name;

@property (nonatomic,copy)NSString * pId;//这个是该对象的唯一标示ID

@property (nonatomic,copy)NSString * type;//对象所属的类型

@property (nonatomic,copy)NSString * level;//用来标示是树状结构中的哪一级

@property (nonatomic,copy)NSString * isOpened;//这里需要构建模型的时候,将isOpened设置为NO(我是用的KVC给数据模型赋值)

@property (nonatomic,retain)NSMutableArray *subItems;//该对象包含子对象,也就是树状的节点

@end

2.将模型建立好,根据模型来进行分组,整理出我们想要的数据结构,具体的方法,我自己写的很绕,但是没有找到好的循环方法....如下:

#pragma mark --- 对对象进行分组

- (NSMutableArray * )groupWithArray:(NSMutableArray *)array{

        NSMutableArray * dataArray = @[].mutableCopy;

         for (ObjModel * rootItem in array) {

                if ([rootItem.type isEqualToString:@"firstLevel"]) {//首先根据类型找出第一级

                      rootItem.level = @"0";//第一级的level

                      rootItem.subItems = @[].mutableCopy;

                     for (ObjModel * firstItem in array) {

                          if ([firstItem.type isEqualToString:@"secondLevel"]&&[firstItem.pId isEqualToString:rootItem.ID]) {//根据类别找出第二级,如果该对象的pId和第一级对象的ID一样,那么它是第二级

                        firstItem.level = @"1";//第二级的level

                         firstItem.subItems = @[].mutableCopy;

                         [rootItem.subItems addObject:firstItem];//将第二级加到第一级中

                             for (ObjModel * thirdItem in array) {

                            if ([thirdItem.type isEqualToString:@"thirdLevel"]&&[thirdItem.pId isEqualToString:firstItem.ID]) {//同理,找出第三级

                                thirdItem.level = @"2";

                                thirdItem.subItems = @[].mutableCopy;

                                [firstItem.subItems addObject:thirdItem];

                                       }

                           }

                }

         }

       [dataArray addObject:rootItem];//把第一级加到dataArray中,也就是tableView的数据源中,此时的数据就是包含了树状结构的

    }

}

return dataArray;

}

3.数据结构整理好,那么初始化tableView,其中tableView要设置为UITableViewStylePlain的样式,

最终要的地方:要实现这个方法的树状结构,最主要的是要用到tableView的两个方法:

- (void)insertRowsAtIndexPaths:(NSArray*)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;//根据indexPath向局部插入新的数据,刷新局部数据

- (void)deleteRowsAtIndexPaths:(NSArray*)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;//根据indexPath向局部删除数据,刷新局部数据

和- (void)reloadRowsAtIndexPaths:(NSArray*)indexPaths withRowAnimation:(UITableViewRowAnimation)animation很类似

我这里就是利用到了点击tableViewCell,判断点击cell所属对象的isOpened,如果是NO,就调用- (void)insertRowsAtIndexPaths:(NSArray*)indexPaths withRowAnimation:(UITableViewRowAnimation)animation

如果是YES,就调用- (void)reloadRowsAtIndexPaths:(NSArray*)indexPaths withRowAnimation:(UITableViewRowAnimation)animation

具体实现的方法:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{

        [tableView deselectRowAtIndexPath:indexPath animated:YES];

        ObjModel * item = self.dataArray[indexPath.row];//得到该cell对应的数据对象

      if ([item.isOpened isEqualToString:@"YES"]) { 

                //这个是树状展开的状态

              NSMutableArray * arr = @[].mutableCopy;

              arr = [self deleteMenuIndexPaths:item];//让树状收起来的方法

              if ([arr count] >0) {

              [self.tableView deleteRowsAtIndexPaths: arr           withRowAnimation:UITableViewRowAnimationMiddle];

          }

}else if([item.isOpened isEqualToString:@"NO"]){

        //这个是树状收起来的状态

         NSMutableArray * arr = @[].mutableCopy;

         arr = [self insertMenuIndexPaths:item];    //让树状展开

         if ([arr count] >0) {

              [self.tableView insertRowsAtIndexPaths:arr withRowAnimation:UITableViewRowAnimationBottom];

       }

  }

}

#pragma mark --- insert

- (NSMutableArray *)insertMenuIndexPaths:(ObjModel *)item{

NSMutableArray * array = @[].mutableCopy;

[self.treeItemsToInsert removeAllObjects];//treeItemsToInsert为需要插入的数据模型数组

[self insertMenuObject:item];

array = [self insertIndexsOfMenuObject:self.treeItemsToInsert];

return array;

}

- (void)insertMenuObject:(ObjModel *)item{

if (item == nil) {

return;

}

NSIndexPath * path = [NSIndexPath indexPathForRow:[self.dataArray indexOfObject:item] inSection:0];

for (int i = 0; i < item.subItems.count; i ++) {

ObjModel * childItem = item.subItems[i];

[self.dataArray insertObject:childItem atIndex:path.row + i + 1];

[self.treeItemsToInsert addObject:childItem];

item.isOpened = @"YES";

}

}

- (NSMutableArray *)insertIndexsOfMenuObject:(NSMutableArray *)array{

NSMutableArray * tempArray = @[].mutableCopy;

for (ObjModel * item in array) {

NSIndexPath * path = [NSIndexPath indexPathForRow:[self.dataArray indexOfObject:item] inSection:0];

[tempArray addObject:path];

}

return tempArray;

}

#pragma mark --- delete

- (NSMutableArray *)deleteMenuIndexPaths:(ObjModel *)item{

NSMutableArray * array = @[].mutableCopy;

[self.treeItemsToRemove removeAllObjects];

[self deleteMenuObject:item];

array = [self deleteIndexsOfMenuObject:self.treeItemsToRemove];

return array;

}

- (void)deleteMenuObject:(ObjModel *)item{

if (item == nil)

{

return ;

}

for (int i = 0; i < item.subItems.count && [item.isOpened isEqualToString:@"YES"]; i ++) {

ObjModel * childItem = item.subItems[i];

[self deleteMenuObject:childItem];

[self.treeItemsToRemove addObject:childItem];

}

item.isOpened = @"NO";

}

- (NSMutableArray *)deleteIndexsOfMenuObject:(NSMutableArray *)array{

NSMutableArray * tempArray = @[].mutableCopy;

NSMutableIndexSet * set;

set = [NSMutableIndexSet indexSet];

for (ObjModel * item in array) {

NSIndexPath * path = [NSIndexPath indexPathForRow:[self.dataArray indexOfObject:item] inSection:0];

[tempArray addObject:path];

[set addIndex:path.row];

}

[self.dataArray removeObjectsAtIndexes:set];

return tempArray;

}

这样,就可以实现tableview的树状结构了.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容