转--动态改变UITableView中的Cell高度

往往在开发iPhone的应用过程中用得最多的应该算是UITableVIew了,凭着IOS给UITableView赋予了这种灵活的框架结构,让它不管在显示列表方面还是在排版方面都有着一定的优势。虽然UITableView功能强大,但是对于一些复杂的应用需求在开发的过程中会出现一些问题,如动态改变UITableView显示的Cell高度就是其中之一

其实想要改变UITableView的Cell高度并不难,UITableView带有一个rowHeight属性,使用他就可以改变高度了。但是这样的改变是把所有的Cell的高度都统一改变了。如果存在不同的内容就有不同的Cell高度,那么这时候rowHeight显得力不从心了。不过iOS似乎考虑到了这一点,在UITableView的UITableViewDelegate委托下有一个委托方法可以动态地指定Cell的高度,其声明如下:

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

此委托方法就可以根据索引位置indexPath来控制返回的Cell高度。可能有人会认为我实现这个委托就可以实现我上面说的效果了吗?是用到这个委托没错,但是使用这个委托时是会存在一些问题的,下面的内容就是要针对这些问题提出我在实际的开发工作中的处理方法,希望通过共享这些思路能够让童鞋们少走点弯路。

其实主要的问题是heightForRowAtIndexPath这个委托的调用时机是早于cellForRowAtIndexPath这个委托方法的(此方法在UITableViewDataSource中定义)我们都知道cellForRowAtIndexPath是用于返回UITableViewCell的方法。那么问题就在这里了,如果我cell还没返回,那我之前怎么能够在heightForRowAtIndexPath中得到cell的高度呢?也许有人会说:我在返回Cell之后重新刷新指定的Cell就能够得到高度了。但其实这个实践起来是很困难的。而还有一点要注意的是在heightForRowAtIndexPath是不能使用UITableView的cellForRowAtIndexPath:返回Cell对象的。否则会导致无限级递归调用引发的堆栈溢出 。原因是调用此方法会触发heightForRowAtIndexPath委托方法。但是要调用也是可以的。解决方法就是先把delegate为空,等获取到Cell后再重新赋值。如:

tableView.delegate=nil;

UITableViewCell *cell=[tableView cellForRowAtIndexPath:indexPath];

tableView.delegate=self;

那么有什么办法可以更加方便实现呢? 我们传统的做法都是在 cellForRowAtIndexPat中排版或者继承UITableViewCell进行排版。而这个也不可避免,但是对于这种动态变更高度的处理,本人认为最好不要直接在cellForRowAtIndexPat中进行排版,应该继承UITableViewCell生成子类,然后在子类里面进行排版工作。因为这跟下面说的解决方法有关。

先说说本人的解决思路吧,其实办法很简单,通过样本Cell来计算高度即可。也就是说我在定义Cell的子类后,在包含UITableView的控制器类或者视图类中定义一个Cell子类的属性,此属性就是专门用于在heightForRowAtIndexPath中计算Cell高度用。这样就能够正确地返回Cell的高度了。先来看看Cell的子类定义:

@interface DemoCell : NSObject{

UILabel *_content;

}

-(CGFloat)contentHeight;

-(void)setContent:(NSString *)content;

@end;

从上面的DemoCell来看其带有一个UILabel对象,这个Cell就是要根据UILabel的内容动态更改高度。其中contentHeight方法是返回Cell的高度。setContent是设置UILabel的内容并计算UILabel的高度。此类很简单要做的就是这样这些操作。然后我们在控制器中定义一个样本Cell专门用于计算Cell的高度。代码如下:

#import "DemoCell.h"

@interface DemoViewController : UIViewController<UITableViewDelegate,UITableViewDataSource>{

UITableView *_tableView;

DemoCell *_sampleCell;

NSArray *_listData;

}

@end;

其中部分实现代码如下:

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

//在此使用样本Cell计算高度。

NSString *content=[_listData objectAtIndex:indexPath.row];

[_sampleCell setContent:content];

return [_sampleCell contentHeight];

}

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

static NSString *[email protected]"DemoCell";

DemoCell *cell=(DemoCell *)[tableView dequeueReusableCellWithIdentifier:cellId];

if(cell==nil){

cell=[[[DemoCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId] autorelease];

}

[cell setContent:[_listData objectAtIndex indexPath:indexPath.row]];

return cell;

}

到此为止我们已经顺利地展示了如何动态变更Cell的高度。只要内容变更我们调用UITableView的reloadData方法就可以刷新整个列表了。Cell如何计算高度本人没有列出来,因为不同的需求导致这部分的实现会不一样。这里只是把思路给大家交代清楚。具体的实现还是要各位童鞋们自己动手操作。

时间: 2024-08-04 23:49:20

转--动态改变UITableView中的Cell高度的相关文章

动态改变ToolBar中的MenuItem

最近项目中开始使用到ToolBar控件,其中有需求需要动态改变ToolBar中的MenuItem.如下图: 1.首先想到的办法是利用ToolBar自带的方法addView()和removeView(). 经测试,动态添加和删除view没有点击效果,需要自己添加,而且如果需要overflow效果,则需要自己实现PopupMenu,所以此方法适用于view比较少的情况. 2.ToolBar是用来替换ActionBar的,用过ActionBar的人应该都熟悉ActionMenuView,使用Actio

动态切换tableView中的cell的种类

为什么要动态切换tableView中cell的种类呢?如果项目经理不出这种需求,你也就见不到这篇文章了:) 效果: 源码: 首先,你要准备3种cell,直接继承系统的就行了. // // RootViewController.m // ChangeCell // // Copyright (c) 2014年 Y.X. All rights reserved. // #import "RootViewController.h" #import "YellowCell.h&quo

UITableView中的cell的优化

1.cell的重用 所谓的cell的重用就是,视图加载的时候只会创建当前视图中的cell,或者比当前视图多一点的cell, 当视图滚动的时候,滚出屏幕的cell会放进缓存中,滚进屏幕的cell会根据Identifier从缓存中获取cell,如此的循环往复,这样只会创建固定的cell对象,节省了内存. 下面是重用cell的代码: //1. 定义重用的标识 static  NSString *reuseId = @"tg"; //2,从缓存中获取重用cell CZTgCell *cell

如何自动在html页面加载时动态改变div等元素的高度和宽度

这里需要用到jquery + css.原理是在页面加载时用javascript去动态改变一个class的高度和宽度.这样结合javascript能动态获取浏览器/页面的高度和宽度,从而使得div能动态的跟随浏览页面的大小变化而变化并且不影响高宽比.下面的代码创建一个手机页面,每一行三个图片分占33%,每个图片div的高和宽会随着浏览器的大小变化而自适应. <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"

IOS 控件 - UITableView 中的cell 自适应高度

当 UITableView 中有一个 label 的内容比较长的时候,就需要 cell 自适应高度来多行展示label: 首先设置 label 的 line 为0: 代码如下: // 为每一个 cell 预设置一个高度,可以提高效率 - (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath { return 44; } // 这里每一个 cell

xib中实现cell高度自适应

iOS8之后的tableview中cell可以设置成自适应高度: 这个新特性,意味着View被Autolayout调整frame后,会自动拉伸和收缩SupView. 具体到Cell,要求cell.contentView的四条边都与内部元素有约束关系. 在TableViewController里 - (void)viewDidLoad { [super viewDidLoad]; //添加这两行代码 self.tableView.estimatedRowHeight = 44.0f; self.t

UITableView中防止cell内容拖动后重叠

由于cell是高效复用的,每当拖动后,在cell.contentView,这些个view就会重叠,网上找了些方法,结合自己的代码,记录下来. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { //这里的reuse,是cell的Identifier     UITableViewCell *cell = [tableView dequeue

使用HVTableView动态展开tableView中的cell

效果: 源码: HVTableView.h 与 HVTableView.m // // HVTableView.h // HRVTableView // // Created by Hamidreza Vakilian on 25/11/2013 // Copyright (c) 2013 Hamidreza Vakilian. All rights reserved. // Website: http://www.infracyber.com/ // Email: [email protect

cocos2d-x改底层之动态改变UIListView中的某项在链表中的位置

先看一下UIListView添加.插入.删除的机制,再来考虑如何移动某一项在链表中得位置. UIListView.h /* 所有项用一个数组来保存 */ CCArray* _items; void ListView::pushBackCustomItem(Widget* item) { /* 向数组中添加一项 */ _items->addObject(item); remedyLayoutParameter(item); addChild(item); _refreshViewDirty = t