RATreeView是树状列表的第三方库,使用方法与UITableView类似,需要返回当前cell,每个树有多少层等,网上的Demo中需要创建TreeModel如下
#import <Foundation/Foundation.h>
@interface RaTreeModel : NSObject
@property (nonatomic,copy) NSString *name;//标题
@property (nonatomic,strong) NSArray *children;//子节点数组
//初始化一个model
- (id)initWithName:(NSString *)name children:(NSArray *)array;
//遍历构造器
+ (id)dataObjectWithName:(NSString *)name children:(NSArray *)children;
@end
在初始化一个RaTreeModel类时,使用类方法进行初始化。name属性是该层的标题,children是子层。
#import "RaTreeModel.h"
@implementation RaTreeModel
- (id)initWithName:(NSString *)name children:(NSArray *)children
{
self = [super init];
if (self) {
self.children = children;
self.name = name;
}
return self;
}
+ (id)dataObjectWithName:(NSString *)name children:(NSArray *)children
{
return [[self alloc] initWithName:name children:children];
}
@end
因为RaTreeView是继承自UITableview,所以可以根据自己的需要自定义tableviewCell。
RATreeView的使用细节与UITableView类似,也要实现两个代理方法,
- (void)viewDidLoad {
[super viewDidLoad];
[self setData];
//创建raTreeView
self.raTreeView = [[RATreeView alloc] initWithFrame:self.view.frame];
//设置代理
self.raTreeView.delegate = self;
self.raTreeView.dataSource = self;
[self.view addSubview:self.raTreeView];
//注册单元格
[self.raTreeView registerNib:[UINib nibWithNibName:@"RaTreeViewCell" bundle:nil] forCellReuseIdentifier:@"RaTreeViewCell"];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark -----------delegate
//返回行高
- (CGFloat)treeView:(RATreeView *)treeView heightForRowForItem:(id)item {
return 50;
}
//将要展开
- (void)treeView:(RATreeView *)treeView willExpandRowForItem:(id)item {
RaTreeViewCell *cell = (RaTreeViewCell *)[treeView cellForItem:item];
cell.iconView.image = [UIImage imageNamed:@"open"];
}
//将要收缩
- (void)treeView:(RATreeView *)treeView willCollapseRowForItem:(id)item {
RaTreeViewCell *cell = (RaTreeViewCell *)[treeView cellForItem:item];
cell.iconView.image = [UIImage imageNamed:@"close"];
}
//已经展开
- (void)treeView:(RATreeView *)treeView didExpandRowForItem:(id)item {
NSLog(@"已经展开了");
}
//已经收缩
- (void)treeView:(RATreeView *)treeView didCollapseRowForItem:(id)item {
NSLog(@"已经收缩了");
}
#pragma mark -----------dataSource
//返回cell
- (UITableViewCell *)treeView:(RATreeView *)treeView cellForItem:(id)item {
//获取cell
RaTreeViewCell *cell = [treeView dequeueReusableCellWithIdentifier:@"RaTreeViewCell"];
//当前item
RaTreeModel *model = item;
//当前层级
NSInteger level = [treeView levelForCellForItem:item];
//赋值
[cell setCellBasicInfoWith:model.name level:level children:model.children.count];
return cell;
}
/**
* 必须实现
*
* @param treeView treeView
* @param item 节点对应的item
*
* @return 每一节点对应的个数
*/
- (NSInteger)treeView:(RATreeView *)treeView numberOfChildrenOfItem:(id)item
{
RaTreeModel *model = item;
if (item == nil) {
return self.modelArray.count;
}
return model.children.count;
}
/**
*必须实现的dataSource方法
*
* @param treeView treeView
* @param index 子节点的索引
* @param item 子节点索引对应的item
*
* @return 返回 节点对应的item
*/
- (id)treeView:(RATreeView *)treeView child:(NSInteger)index ofItem:(id)item {
RaTreeModel *model = item;
if (item==nil) {
return self.modelArray[index];
}
return model.children[index];
}
//cell的点击方法
- (void)treeView:(RATreeView *)treeView didSelectRowForItem:(id)item {
//获取当前的层
NSInteger level = [treeView levelForCellForItem:item];
//当前点击的model
RaTreeModel *model = item;
if (model.children.count ==0 &&model.children ==nil) {
NSLog(@"没有数据啦-----------");
}
NSLog(@"点击的是第%ld层,name=%@",level,model.name);
}
//加载数据
- (void)setData {
//宝鸡市 (四层)
RaTreeModel *zijingcun = [RaTreeModel dataObjectWithName:@"紫荆村" children:nil];
RaTreeModel *chengcunzheng = [RaTreeModel dataObjectWithName:@"陈村镇" children:@[zijingcun]];
RaTreeModel *fengxiang = [RaTreeModel dataObjectWithName:@"凤翔县" children:@[chengcunzheng]];
RaTreeModel *qishan = [RaTreeModel dataObjectWithName:@"岐山县" children:nil];
RaTreeModel *baoji = [RaTreeModel dataObjectWithName:@"宝鸡市" children:@[fengxiang,qishan]];
//西安市
RaTreeModel *yantaqu = [RaTreeModel dataObjectWithName:@"雁塔区" children:nil];
RaTreeModel *xinchengqu = [RaTreeModel dataObjectWithName:@"新城区" children:nil];
RaTreeModel *xian = [RaTreeModel dataObjectWithName:@"西安" children:@[yantaqu,xinchengqu]];
RaTreeModel *shanxi = [RaTreeModel dataObjectWithName:@"陕西" children:@[baoji,xian]];
[self.modelArray addObject:shanxi];
}
而我们一般做网络接口请求的时候返回的数据可能是递归数组,所以要做处理。返回的数据首先是数组,每个数组元素是一个数据字典类型,其中有可能有属性name,children等,其中children又是一个数组,数组可能是空,也可能每一个元素又是数据字典类型,而其中的属性同样是name,children等,所以型成了这样一个递归类型。
处理逻辑一般是将返回的数据存储在上述中RaTreeModel中,在将其存入数组中,首先forin遍历数组,每遍历一次创建一个RaTreeModel,随后获取children属性中的数组,判断数组是否为空,为空则model初始化的时候为children属性赋值nil,不为空则我们要继续操作,遍历children数组->创建model->获取children数组的子children属性判断是否为空,如此反复进行了递归操作。具体的实现步骤如下
-(NSArray *)getDeptData:(NSArray *)array{
NSMutableArray *treeArray =[NSMutableArray array];
for (NSDictionary *dic in array) {
RaTreeModel *tree;
NSArray *childrenArray =(NSArray *)[dic objectForKey:@"children"];
if (childrenArray.count !=0 && childrenArray !=nil) {
tree = [RaTreeModel dataObjectWithName:[dic objectForKey:@"deptName"] children:[self getDeptData:childrenArray];];
}else{
tree =[RaTreeModel dataObjectWithName:[dic objectForKey:@"deptName"] children:nil];
}
[treeArray addObject:tree];
tree = nil;
}
return treeArray;
}