UITableVIew是iOS开发中使用最为广泛的一种控件,对于UITableView的基本用法本文不做探讨,本文主要是针对UITableView的展开与收缩进行阐述,在文章的后面也会探讨一下横向table的用法:

1. UITableView的展开与收缩

下面通过两幅图来了解UITableView的展开与收缩的效果:

这种展开与收缩的原理其实非常简单,在使用该TableVIew的时候需要准备两个自定义的Cell,一个是未展开情况下的Cell,一个是展开后
的Cell,当点击某一行的展开/收缩按钮时,将该行替换为展开/收缩后的Cell,并将其他所有行全部收缩,原理很简单,下面上代码:

(1)扩展UITableView的部分方法:

创建一个UITableVIew的子类,名称为:ExtensibleTableView

.h文件中:

@protocol ExtensibleTableViewDelegate <NSObject>

@required

//返回展开之后的cell

- (UITableViewCell *)tableView:(UITableView *)tableView extendedCellForRowAtIndexPath:(NSIndexPath *)indexPath;

//返回展开之后的cell的高度

- (CGFloat)tableView:(UITableView *)tableView extendedHeightForRowAtIndexPath:(NSIndexPath *)indexPath;

@end

@interface ExtensibleTableView :
UITableView

{

//当前被展开的索引

NSIndexPath *currentIndexPath;

//  id<ExtensibleTableViewDelegate> delegate_extend;

}

@property(nonatomic,retain)id delegate_extend;

@property(nonatomic,retain)NSIndexPath *currentIndexPath;

//将indexPath对应的row展开

- (void)extendCellAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated goToTop:(BOOL)goToTop;

//将展开的cell收起

- (void)shrinkCellWithAnimated:(BOOL)animated;

//查看传来的索引和当前被选中索引是否相同

- (BOOL)isEqualToSelectedIndexPath:(NSIndexPath *)indexPath;

@end

在.m文件中

@implementation ExtensibleTableView

@synthesize delegate_extend;

@synthesize currentIndexPath;

- (id)init

{

self.currentIndexPath =nil;

return [superinit];

}

//重写设置代理的方法,使为UITableView设置代理时,将子类的delegate_extend同样设置

- (void)setDelegate:(id<UITableViewDelegate>)delegate

{

self.delegate_extend = delegate;

[super setDelegate:delegate];

}

/*

将indexPath对应的row展开

params:

animated:是否要动画效果

goToTop:展开后是否让到被展开的cell滚动到顶部

*/

- (void)extendCellAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated goToTop:(BOOL)goToTop

{

//被取消选中的行的索引

NSIndexPath *unselectedIndex = [NSIndexPathindexPathForRow:[self.currentIndexPathrow]inSection:[self.currentIndexPathsection]];

//要刷新的index的集合

NSMutableArray *array1 = [[NSMutableArrayalloc]init];

//若当前index不为空

if(self.currentIndexPath)

{

//被取消选中的行的索引

[array1 addObject:unselectedIndex];

}

//若当前选中的行和入参的选中行不相同,说明用户点击的不是已经展开的cell

if(![selfisEqualToSelectedIndexPath:indexPath])

{

//被选中的行的索引

[array1 addObject:indexPath];

}

//将当前被选中的索引重新赋值

self.currentIndexPath = indexPath;

if(animated)

{

[selfreloadRowsAtIndexPaths:array1withRowAnimation:UITableViewRowAnimationFade];

}

else

{

[selfreloadRowsAtIndexPaths:array1withRowAnimation:UITableViewRowAnimationNone];

}

if(goToTop)

{

//tableview滚动到新选中的行的高度

[selfscrollToRowAtIndexPath:indexPathatScrollPosition:UITableViewScrollPositionTopanimated:YES];

}

[array1 release];

}

//将展开的cell收起

- (void)shrinkCellWithAnimated:(BOOL)animated

{

//要刷新的index的集合

NSMutableArray *array1 = [[NSMutableArrayalloc]init];

if(self.currentIndexPath)

{

//当前展开的cell的索引

[array1 addObject:self.currentIndexPath];

//将当前展开的cell的索引设为空

self.currentIndexPath =nil;

[selfreloadRowsAtIndexPaths:array1withRowAnimation:UITableViewRowAnimationFade];

}

[array1 release];

}

//查看传来的索引和当前被选中索引是否相同

- (BOOL)isEqualToSelectedIndexPath:(NSIndexPath *)indexPath

{

if(self.currentIndexPath)

{

return ([self.currentIndexPathrow] == [indexPathrow]) && ([self.currentIndexPathsection]
== [indexPathsection]);

}

return
NO;

}

/*

重写了这个方法,却无效,因为这个方法总在didSelect之前调用,很奇怪。因为无法重写该方法,所以ExtensibleTableView不算完善,因为还有额外的代码需要在heightForRowAtIndexPath和cellForRowAtIndexPath中。哪个找到完善的方法后希望可以与qq82934162联系或者在http://borissun.iteye.com来留言

*/

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

{

if([self.currentIndexPathrow] == [indexPathrow])

{

return [self.delegate_extendtableView:selfextendedHeightForRowAtIndexPath:indexPath];

}

return [superrowHeight];

}

@end

这个类时在UITableView的基础上扩展了两个方法,一个是展开情况下的CellForRow方法,一个是在展开情况下的返回heightForRow方法

(2) 准备两个自定义的Cell

如下图:

          

可以看出这两个Cell上半部分完全一样,主要差别是展开后的Cell多了下面的一部分

(3) 在ViewController中实现该TableVIew的部分方法:

在ViewController文件中:

ExtensibleTableView *ccTableView=[[ExtensibleTableViewalloc]initWithFrame:CGRectMake(0,163,ModelSize.width,ModelSize.height-20-44-49-163-40)];

ccTableView.delegate=self;

ccTableView.dataSource=self;

ccTableView.delegate_extend=self;     //这个代理就是展开行的代理

下面实现UITableVIew的方法:

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

{

return
[dataArr count];

}

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

{

CGFloat hei=0.0f;

if([ccTableViewisEqualToSelectedIndexPath:indexPath])

{

return [selftableView:ccTableViewextendedHeightForRowAtIndexPath:indexPath];//展开后的行高

}else

{

hei= 50;   // 未展开下的行高

}

return hei;

}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

{

//若当前行被选中,则返回展开的cell

if([ccTableViewisEqualToSelectedIndexPath:indexPath])

{

return [selftableView:ccTableViewextendedCellForRowAtIndexPath:indexPath];

}

static NSString *CellIdentifier =@"CCCell";

UINib *nib = [UINibnibWithNibName:@"CCCell"bundle:nil];

[tableView registerNib:nib
forCellReuseIdentifier:CellIdentifier];

CCCell *cell = [tableView
dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell ==
nil)

{

cell = [[[CCCell
alloc]

initWithStyle:UITableViewCellStyleDefault

reuseIdentifier:CellIdentifier]autorelease];

}

cell.selectionStyle=UITableViewCellSelectionStyleNone;

//在此设置Cell的相关数据

UIButton *btn=[[UIButtonalloc]initWithFrame:CGRectMake(ModelSize.width-45,3,45,
45)];

[btn setImage:[UIImageselfimageNamed:@"tragile_down@2x.png"]forState:UIControlStateNormal];

btn.tag=indexPath.row;

[btn addTarget:selfaction:@selector(operateCell:)forControlEvents:UIControlEventTouchUpInside];

[cell addSubview:btn];

[btn release];

return cell;

}

//返回展开之后的cell

- (UITableViewCell *)tableView:(UITableView *)tableView extendedCellForRowAtIndexPath:(NSIndexPath *)indexPath

{

//每个cell的标识

NSString *CellTableIdentifier=@"CCopenCell";

//获得cell

UINib *nib = [UINibnibWithNibName:@"CCopenCell"bundle:nil];

[tableView registerNib:nib
forCellReuseIdentifier:CellTableIdentifier];

CCopenCell *cell = [tableView
dequeueReusableCellWithIdentifier:CellTableIdentifier];

if (cell == nil)

{

cell = [[[CCopenCell
alloc]

initWithStyle:UITableViewCellStyleDefault

reuseIdentifier:CellTableIdentifier]autorelease];

cell.frame=CGRectMake(0,0,ModelSize.width
,0);

}

cell.selectionStyle=UITableViewCellSelectionStyleNone;

// 在此设置cell的相关数据

UIButton *btn=[[UIButtonalloc]initWithFrame:CGRectMake(ModelSize.width-45,3,45,45)];

[btn setImage:[UIImageselfimageNamed:@"tragile_down@2x.png"]forState:UIControlStateNormal];

btn.tag=indexPath.row;

[btn addTarget:selfaction:@selector(operateCell:)forControlEvents:UIControlEventTouchUpInside];

[cell addSubview:btn];

[btn release];

return cell;

}

//返回展开之后的cell的高度

- (CGFloat)tableView:(UITableView *)tableView extendedHeightForRowAtIndexPath:(NSIndexPath *)indexPath{

return 95;

}

OK,以上就是展开与收缩TableVIew的代码,本人已经多次使用,确认无误,如果疑问请联系

最后我们看看横向TableVIew的实现方法:

_tableView.transform
= CGAffineTransformMakeRotation(-M_PI / 2);

cell.contentView.transform
= CGAffineTransformMakeRotation(M_PI / 2); 
方法二:横向UITableView已经有开源实现了  ,EasyTableView,https://github.com/alekseyn/EasyTableView

ios知识点总结——UITableView的展开与收缩及横向Table的更多相关文章

  1. 【iOS系列】-UITableViewCell的展开与收缩的实现思路

    UITableViewCell的展开与收缩的实现思路 现在项目中很多地方都会用到,所以我这里介绍一种可以复用的思路,这与文章后面的Swift的实现思路不同,具体大家可自行对比. Demo项目地址 开始 ...

  2. iOS开发系列--UITableView全面解析

    --UIKit之UITableView 概述 在iOS开发中UITableView可以说是使用最广泛的控件,我们平时使用的软件中到处都可以看到它的影子,类似于微信.QQ.新浪微博等软件基本上随处都是U ...

  3. 在iOS中怎样创建可展开的Table View?(下)

    接上篇:在iOS中怎样创建可展开的Table View?(上) 展开和合拢 我猜这部分可能是你最期望的了,因为本次教程的目标将会在在部分实现.第一次我们设法让顶层的cell,在它们点击的时候展开或者合 ...

  4. IOS学习笔记48--一些常见的IOS知识点+面试题

      IOS学习笔记48--一些常见的IOS知识点+面试题   1.堆和栈什么区别? 答:管理方式:对于栈来讲,是由编译器自动管理,无需我们手工控制:对于堆来说,释放工作由程序员控制,容易产生memor ...

  5. ios-tableViewcell展开与收缩动画处理

    [前言] 在使用华尔街见闻 app 时,看到它的 tableVeiw 上的 cell 具有很好的展开与收缩功能.于是自己想了一下实现,感觉应该挺简单的,于是心痒痒写个 demo 实现一波.华尔街见闻 ...

  6. DataGridView之行的展开与收缩

    很多数据都有父节点与子节点,我们希望单击父节点的时候可以展开父节点下的子节点数据. 比如一个医院科室表,有父科室与子科室,点击父科室后,在父科室下面可以展现该科室下的所有子科室. 我们来说一下在Dat ...

  7. IOS开发中UITableView(表视图)的滚动优化及自定义Cell

    IOS开发中UITableView(表视图)的滚动优化及自定义Cell IOS 开发中UITableView是非常常用的一个控件,我们平时在手机上看到的联系人列表,微信好友列表等都是通过UITable ...

  8. dhtmlxtree 节点 展开收缩:新增了直接点 文本内容 也 实现了 展开收缩 功能(并记住了展开、收缩状态)

    dhtmlxtree 节点 展开收缩通常情况我们按 +- 就实现了 展开收缩 功能,为了方便我们新增了直接点 文本内容 也 实现了 展开收缩 功能(并记住了展开.收缩状态) tree = new dh ...

  9. js 实现内容的展开和收缩

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

随机推荐

  1. 鸟哥的linux私房菜学习-(二)VMware虚拟机及linux系统安装过程

    一.安装虚拟机 1.虚拟机常用版本及注册码地址:https://pan.baidu.com/s/1dFnkBrN#list/path=%2FSoftware%20Big%2FVMware%20Work ...

  2. python pandas 合并数据函数merge join concat combine_first 区分

    pandas对象中的数据可以通过一些内置的方法进行合并:pandas.merge,pandas.concat,实例方法join,combine_first,它们的使用对象和效果都是不同的,下面进行区分 ...

  3. 三栏布局之 css3 calc和 flex

    圣杯布局的实现,有很多种. 大致都是借助 padding, margin, float之类的,当然这是传统的实现方式.更多的参考方式圣杯布局小结. 这里说的是用css3 cal 和flex来实现,因为 ...

  4. MyEclipse过期后怎么破解

    方法一:写一个程序生成Subscriptioncode import java.io.*; public class MyEclipseGen { private static final Strin ...

  5. tomcat 发布简单的html网站

    1.建立一个文件夹D:\Demo 2.在Demo目录下,建立一个WEB-INF的文件夹并将web.xml放在里面,D:\Demo\WEB-INF\web.xml 3.将index.html文件放在De ...

  6. 【读书笔记】【深入理解ES6】#9-JavaScript中的类

    大多数面向对象的编程语言都支持类和类继承的特性,而JavaScript却不支持这些特性,只能通过其他方法定义并关联多个相似的对象.这个状态一直从ECMAScript 1持续到ECMAScript 5. ...

  7. Go 语言打包静态文件

    对于 Go 语言开发者来说,在享受语言便利性的同时,最终编译的单一可执行文件也是我们所热衷的.但是,一旦遇到我们需要分发的东西不只有可执行文件的时候,事情就变得稍微有点复杂了,例如,需要分发个默认的配 ...

  8. gradle学习记录

    一.Gradle简介 Gradle是Android现在主流的编译工具,虽然在Gradle出现之前和之后都有对应更快的编译工具出现,但是Gradle的有时就在于它是亲儿子,Gradle确实比较慢,这和它 ...

  9. FPGA学习之路——一路走来

    既然选择了远方,便不顾风雨兼程,一路走下去. —韩彬 在看bingo的书时,看到这样写到.做什么事情都不容易,学习也是,所以一个词很重要不忘初心.作为一名大二的学生,我很高兴能够将自己学习FPGA的过 ...

  10. Django 1.10中文文档-第一个应用Part1-请求与响应

    在本教程中,我们将引导您完成一个投票应用程序的创建,它包含下面两部分: 一个可以进行投票和查看结果的公开站点: 一个可以进行增删改查的后台admin管理界面: 我们假设你已经安装了Django.您可以 ...