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的树状结构了.

你可能感兴趣的:(ios UITabelView实现树状解构的一种方法)