当前位置: 首页 > 工具软件 > RATreeView > 使用案例 >

RATreeView使用细节

松烨烨
2023-12-01

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;
}



 类似资料: