版权声明:本文为博主原创文章。未经博主同意不得转载。

https://blog.csdn.net/u012951123/article/details/36421939

由于项目须要用到树状列表,能够添加成员变量,于是用了第三方RATreeView开元库,头一次使用,安装github上的使用说明和Demo跑了一下,挺惬意,添加成员什么的都非常easy,和tableview非常像是,可是在处理选择的cell时我纠结了一会,用惯了tableview的index:index.row   index.section等。猛然接触到RATreeView处理时,不知道该怎样办了,以下记录的我学习过程,

以下先看下。RATreeView是怎样管理选择这个动作的,方法例如以下:

<span style="font-size:18px;">//Managing Selections
- (id)treeView:(RATreeView *)treeView willSelectRowForItem:(id)item treeNodeInfo:(RATreeNodeInfo *)treeNodeInfo;
- (void)treeView:(RATreeView *)treeView didSelectRowForItem:(id)item treeNodeInfo:(RATreeNodeInfo *)treeNodeInfo;
- (id)treeView:(RATreeView *)treeView willDeselectRowForItem:(id)item treeNodeInfo:(RATreeNodeInfo *)treeNodeInfo;
- (void)treeView:(RATreeView *)treeView didDeselectRowForItem:(id)item treeNodeInfo:(RATreeNodeInfo *)treeNodeInfo;</span>

事实上我们实用的信息都存储在treeNodeInfo中。以下我们来分析一下 RATreeNodeInfo

@property (nonatomic, getter = isExpanded, readonly) BOOL expanded;  //推断是否展开
@property (nonatomic, readonly) NSInteger treeDepthLevel;   //树状展开的深度。也就是层次级别

@property (nonatomic, readonly) NSInteger siblingsNumber; 
@property (nonatomic, readonly) NSInteger positionInSiblings;    //在每一个层次中。我们选择的单元处于的位置,也就是索引

@property (strong, nonatomic, readonly) RATreeNodeInfo *parent;   //我们选择的cell的上一级信息汇总
@property (strong, nonatomic, readonly) NSArray *children;   //我们选择的cell 的子类包括的成员数组

@property (strong, nonatomic, readonly) id item;   
实用的信息我都已经标出来了。

可能到如今你还混乱则呢。什么是树状结构,什么是层次?以下我们来张图分析一下:

以下通过我项目中的代码片端来分析一下datasource 和delegate 方法的使用方法:

#pragma mark TreeView Delegate methods
- (CGFloat)treeView:(RATreeView *)treeView heightForRowForItem:(id)item treeNodeInfo:(RATreeNodeInfo *)treeNodeInfo
{
return 60;//这里范围单元个的高度。能够单独处理每一个单元格,通过以下就知道怎样单独处理我们想要的了
} - (NSInteger)treeView:(RATreeView *)treeView indentationLevelForRowForItem:(id)item treeNodeInfo:(RATreeNodeInfo *)treeNodeInfo
{
return 3 * treeNodeInfo.treeDepthLevel; //这个我还没理解。应该是返回我们要使用的文件夹深度。几层吧,我项目中就用到两层,所以没改动
} //这个函数决定 能否够展开。通过设定我们能够设置哪些单元格能够展开到下一层,哪些不能够展开
- (BOOL)treeView:(RATreeView *)treeView shouldExpandItem:(id)item treeNodeInfo:(RATreeNodeInfo *)treeNodeInfo
{
RADataObject *objc = (RADataObject *)item;
if ([objc.name isEqualToString:@"宝贝成员"]) { //事实上,这里的item就是我们点击的单元cell。当中RADataObject不知道的话。建议去下载一下treeView的源代码看看就会明确了
return YES; //事实上我们还能够通过treeNodeInfo来做,由于它包括了我们所须要的全部信息
}
return NO;
} //这个函数:但我们数据又一次载入时,我们来决定,展开哪个单元。在项目中我的成员列表刷新后,要又一次载入数据,同一时候要展开我的成员列表
 - (BOOL)treeView:(RATreeView *)treeView shouldItemBeExpandedAfterDataReload:(id)item treeDepthLevel:(NSInteger)treeDepthLevel
{
RADataObject *objec = (RADataObject *)item;
if ([objec.name isEqualToString:@"宝贝成员"]) {
return YES;
}
return NO;
} //这个看字面意识就理解了,在单元格显示之前(或者说将要显示时)我们能够做些设置,这里是设置对应深度的颜色背景
- (void)treeView:(RATreeView *)treeView willDisplayCell:(UITableViewCell *)cell forItem:(id)item treeNodeInfo:(RATreeNodeInfo *)treeNodeInfo
{
if (treeNodeInfo.treeDepthLevel == 0) {
cell.backgroundColor = UIColorFromRGB(0xF7F7F7);
} else if (treeNodeInfo.treeDepthLevel == 1) {
cell.backgroundColor = UIColorFromRGB(0xD1EEFC);
} else if (treeNodeInfo.treeDepthLevel == 2) {
cell.backgroundColor = UIColorFromRGB(0xE0F8D8);
}
} //这里就是我们最熟悉的点击cell处理函数,看代码慢慢体会treeNodeInfo的使用。不想多说了
-(void)treeView:(RATreeView *)treeView didSelectRowForItem:(id)item treeNodeInfo:(RATreeNodeInfo *)treeNodeInfo
{
NSInteger count = treeNodeInfo.parent.children.count;//你点击的该单元的父节点有多少个成员
NSInteger treeDpthLevelValue = treeNodeInfo.treeDepthLevel;
NSInteger positionInSiblingsValue = treeNodeInfo.positionInSiblings;
if (treeDpthLevelValue == 0)
{
if (positionInSiblingsValue == 0 ) {
//回到首页
[self.mm_drawerController closeDrawerAnimated:YES completion:nil];
}else if(positionInSiblingsValue == 1){
//不处理
}else if(positionInSiblingsValue == 2){
//进入发烧预警 }else if(positionInSiblingsValue == 3){
//推荐给朋友
}else if(positionInSiblingsValue == 4){
//设置
SettingViewController *setting = [[SettingViewController alloc]initWithNibName:@"SettingViewController" bundle:nil];
[self presentViewController:setting animated:YES completion:nil];
}
}else if (treeDpthLevelValue == 1)
{
if (count == 1)
{
//进入添加成员设置页面
AddMemberViewController *addVC = [[AddMemberViewController alloc]initWithNibName:@"AddMemberViewController" bundle:nil];
[self presentViewController:addVC animated:YES completion:nil]; }else
{
if (positionInSiblingsValue == count - 1) {
//进入添加成员设置页面
NSLog(@"进入添加成员页面");
//AddMemberViewController *addVC = [[AddMemberViewController alloc]initWithNibName:@"AddMemberViewController" bundle:nil];
[self presentViewController:addVC animated:YES completion:nil]; }else
{
//设置用户选择的成员标志
self.selectedMemberIndex = positionInSiblingsValue;
NSLog(@"用户选择的第 %li 个成员",self.selectedMemberIndex);
}
}
}
}
#pragma mark TreeView Data Source
//数据源处理,相当于UITableViewCell处理,关键还是理解treeNodeInfo概念
- (UITableViewCell *)treeView:(RATreeView *)treeView cellForItem:(id)item treeNodeInfo:(RATreeNodeInfo *)treeNodeInfo
{
NSInteger numberOfChildren = [treeNodeInfo.children count];
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"cell"]; // cell.detailTextLabel.text = [NSString stringWithFormat:@"Number of children %d", numberOfChildren];
cell.textLabel.text = ((RADataObject *)item).name;
// cell.selectionStyle = UITableViewCellSelectionStyleNone;
if (treeNodeInfo.treeDepthLevel == 0) {
cell.detailTextLabel.textColor = [UIColor blackColor];
}
return cell;
}
//返回每一层包括成员的个数,来制表
- (NSInteger)treeView:(RATreeView *)treeView numberOfChildrenOfItem:(id)item
{
if (item == nil) {
return [self.data count];
}
RADataObject *data = item;
return [data.children count];
}
//返回对象
- (id)treeView:(RATreeView *)treeView child:(NSInteger)index ofItem:(id)item
{
RADataObject *data = item;
if (item == nil) {
return [self.data objectAtIndex:index];
}
return [data.children objectAtIndex:index];
} //这里是我想简单、单独说的他们都是delegate方法,可是是用来管理单元cell编辑的,比方删除等
//看各个函数的名字都知道什么意识了,过程能够这么理解:将要開始、运行、运行后
#pragma mark -
#pragma mark TreeView Editing
//这里决定单元格是否可编辑
-(BOOL)treeView:(RATreeView *)treeView canEditRowForItem:(id)item treeNodeInfo:(RATreeNodeInfo *)treeNodeInfo
{
return YES;
}
-(void)treeView:(RATreeView *)treeView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowForItem:(id)item treeNodeInfo:(RATreeNodeInfo *)treeNodeInfo
{ NSLog(@"self.objcArray == %@",self.objcArray);
if (treeNodeInfo.treeDepthLevel == 1) {
NSInteger index = treeNodeInfo.positionInSiblings;
[self.objcArray removeObjectAtIndex:index];
_willDeleteMember = [self.members objectAtIndex:index];//将要在数据库中删除的成员对象
}
_membersObject = [RADataObject dataObjectWithName:@"宝贝成员" children:[self.objcArray copy]];
[self.data replaceObjectAtIndex:1 withObject:_membersObject]; [self.treeView reloadData]; }
-(void)treeView:(RATreeView *)treeView willBeginEditingRowForItem:(id)item treeNodeInfo:(RATreeNodeInfo *)treeNodeInfo
{
NSLog(@"willBeginEditinRow"); }
-(void)treeView:(RATreeView *)treeView didEndEditingRowForItem:(id)item treeNodeInfo:(RATreeNodeInfo *)treeNodeInfo
{
//展开成员列表
//[self.treeView expandRowForItem:treeNodeInfo.parent withRowAnimation:RATreeViewRowAnimationMiddle]; //expands Row
//[self.treeView expandRowForItem:item];
NSLog(@"DidEnditing....."); //完毕编辑后。同步数据库:数据库也要删除对应的成员
NSString *path = [self getDBPath];
FMDatabase *membersDB = [FMDatabase databaseWithPath:path];
if (![membersDB open]) {
NSLog(@"Failed to open membersDB");
[membersDB close];
} BOOL rs = [membersDB executeUpdate:@"DELETE FROM Member WHERE Name = ? ",_willDeleteMember.name];
if (!rs) {
return;
}
NSLog(@"success delete");
[membersDB close];
}

项目中占时用到这么多,以后会慢慢完好的

第三方库RATreeView的使用记录的更多相关文章

  1. Android开发中导入第三方库所遇问题记录

    1.重复循环依赖的问题 (1)需求 如下图所示: 在Android 项目中,采用模块化开发,一个是主跑application--Mudule A,另外一个是library--Library B 1)M ...

  2. 对于pod导入第三方库文件终端语言记录

    //换成 pod install --verbose --no-repo-update //生成Podfile文件 touch Podfile 加上--verbose --no-repo-update ...

  3. android studio 导入第三方库的记录

    android studio 导入第三方库的记录.jar包 和 库 一.jar包 1.jar包的话很简单,首先换成project模式,将你要用的jar包复制到lib下面.如图 2.然后右键选择Add ...

  4. python中常用第三方库记录

    python中有很多很好用的第三方库,现在记录一下这些库以及如何下载 一.virtualenv,这是一个可以将生产环境隔离开的python库,非常好用 在linux下使用pip install vir ...

  5. ffmpeg第三方库编译记录

    最近在研究ffmpeg的编译,之前使用的Ubuntu,需要安装虚拟机,非常麻烦,所以后来改研究在Windows平台编译. 一开始遇到很多挫折,参考了网上很多的帖子,但要么不全要么内容已过期,经过我的反 ...

  6. 使用pip安装第三方库报错记录

    今天在使用pycharm导入第三方库的时候,报了好多超时错误,还有标题中的找不到版本,应该是网络的原因,记录下解决的办法: raise ReadTimeoutError(self._pool, Non ...

  7. 调用第三方库时需注意MD/MT的链接编译方式(遇到的坑记录)

    MD与/MT编译 1./MD是动态库链接方式编译 (DEBUG版本是/MDd) 2./MT是静态库链接方式编译 (DEBUG版本是/MTd) 编译器不会检查到的问题 我今天遇到的记录下来 当你调用第三 ...

  8. Egret 集成第三方库 记录

    引入第三方库pureMVC 这次我们要使用到一个mvc开发框架-pureMVC,熟悉as3的朋友一定也对这个框架不陌生吧.不熟悉的也没关系,这个框架不是这次的主角.我们从 这里 下载pureMVC的T ...

  9. 记录一些好用的iOS第三方库

    CBStoreHouseRefreshControl:一个效果很酷炫的下拉刷新控件. ZLSwipeableView:ZLSwipeableView是一个方便做出卡片效果的UI库,支持各种卡片的滑动效 ...

随机推荐

  1. vmstat命令——监控给定时间间隔的服务器的状态值

    vmstat n m 时间间隔为n秒,采集m组数据vmstat n     时间间隔为n秒 # vmstat 2 3 procs -----------memory---------- ---swap ...

  2. step1: python & scrapy安装

    #首先安装python,这里安装python所需依赖包yum install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-dev ...

  3. JS将文件像form表单一样提交到后台

    这是很简单.. HTML <div> <input type="file" id="myfile"> <input type=&q ...

  4. CentOS7 一键安装KMS服务【整理】

    KMS,是 Key Management System 的缩写,也就是密钥管理系统.这里所说的 KMS,毋庸置疑就是用来激活 VOL 版本的 Windows 和 Office 的 KMS 啦.经常能在 ...

  5. Java - 网络IO的阻塞

    最近学习时碰到事件驱动和非阻塞的相关知识,随之想到了Java中的Reactor.io与nio的一些东西:在前辈的博客上翻了翻.复习复习,在此记录一番. 实在找不到比较大点的东西,于是随便弄了个压缩包, ...

  6. MVC设计模式实现权限管理登录,超详细

    功能实现:在页面输入给定的用户名之一,可以显示当前用户的权限,也可以在页面更改该用户的权限,更新之后保存.像下面这样. 填写用户名提交: 显示用户AAA的权限: 修改权限(增加article3): 点 ...

  7. python 中str字符串 和list列表基本操作总结

    s = '#afsfdf222#' print(s.capitalize()) # 首字母大写其他字母小写 print(s.center(20, '%')) # 居中并在空白处添加指定字符 print ...

  8. VUE的两种跳转push和replace对比区别

    router.push(location) 在vue.js中想要跳转到不同的 URL,需要使用 router.push 方法. 这个方法会向 history 栈添加一个新的记录,当用户点击浏览器后退按 ...

  9. 移动web中的幻灯片切换效果

    百度或者谷歌下类似的插件有很多,原理都差不多,关键适合自己的项目,如果移动端要引入jquery这么大的插件,只能呵呵了.... 下面是工作中针对webkit内核的浏览器写的,html很简单: < ...

  10. Express (Routing、Middleware、托管静态文件、view engine 等等)

    1. Express 简介 Express 是基于 Node.js 平台,快速.开放.极简的 web 开发框架,它提供一系列强大的特性,帮助你创建各种 Web 和移动设备应用. Express 不对 ...