iOS-动态调整UITableViewCell的高度
OS-动态调整UITableViewCell的高度iOS开发文档, by 友盟翻译组 stefaliu.
大概你第一眼看来,动态调整高度是一件不容易的事情,而且打算解决它的第一个想法往往是不正确的。在这篇文章中我将展示如何使图表单元格的高度能根据里面文本内容来动态改变,同时又不必子类化UITableViewCell。你当然可以通过子类化它来实现,但是这样做会使得代码复杂因为设置高度是在图表本身的实例上而不是对单元格操作。下面你将会看到这其实是一件轻而易举的事情。对于图表来说能够动态调整高度是件很有意义的事情,我首先想到的需要这个功能的是当显示一列长度会变化的文本列表时,如果文本内容较少,它或许能够适合正常的单元格label,但是如果文本变长,就不得不重新设置单元格大小以便于显示全部的文本内容。我总结了重新设置单元格大小的主要步骤如下:
1 创建并添加一个UILabel作为单元格cell的子视图; 2 在UITableView的委托方法: (CGFloat)tableView:(UITableView*)tableViewheightForRowAtIndexPath: (NSIndexPath *) indexPath中计算高度 3 在UITableView的委托方法: (UITableViewCell*)tableView:(UITableView*)tableViewcellForRowAtIndexPath: (NSIndexPath *) indexPath中计算UILabel的框大小。
下面我要详细介绍这些步骤,首先看一下程序输出截图: 在普通的图表中,你可以简单地用下面的方法设置单元格内label的文本内容:
[[cell textLabel] setText:@"Text for the current cell here."];
也许你认为这样做就可以完全控制UILabel了,但是我发现我的任何要改变UILabel框大小的尝试都失败了,因此这并不是实现动态调整大小的一个好的候选方案。
我们需要设计一个UILabel然后把它添加到单元格的内容视图中。要实现它需要调用-cellForRowAtIndexPath,大致内容如下所示:
1 |
- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath |
这并不是完整的代码因为我们仅仅在创建单元格的时候初始化它的label,这段代码对应调用-dequeueReusableCellWithIdentifier之后的判断模块if(cell == nil)。 在这里我想强调两点:第一个,我们可以注意到label有一个标签与其对应,因为调用了-setTag:1。当cell不等于nil时这个标签可以用到。第二点,我们通过调用[[cell contentView] addSubview:label]来将label添加到单元格的内容视图中,这个只是在label初始化的时候用到。每调用这个函数都会添加label 到子视图序列中。下面我们会将这段代码补充完整,但之前先让我们看一下如何设置cell的高度。
计算cell的高度
在一个复杂的cell中,计算高度可能比较困难,但是你只需要关心那些高度会变化的部件就可以了。在我的例子中,唯一需要处理的就是添加到单元格中的label。我们根据文本的大小来计算cell 的高度,而文本的大小取决于文本的长度和文本字体。NSString类提供了函数-sizeWithFont来方便我们获取cell 的大小。下面的代码介绍了函数-heightForRowAtIndexPath:
1 |
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath; |
你会注意到我们用到了几个常量来计算cell 的大小,它们的定义如下所示:
#define FONT_SIZE 14.0f
#define CELL_CONTENT_WIDTH 320.0f
#define CELL_CONTENT_MARGIN 10.0f
常量CELL_CONTENT_WIDTH是整个cell的宽度。CELL_CONTENT_MARGIN是我们定义的页边空白,FONT_SIZE是我们采用文本的字体大小。
首先我们要创建一个内容宽度的约束条件。CGSizeMake的第一个参量是总共的内容宽度减去两个页边空白。因为左边和右边各有一个页边空白。第二个参数是我们提供的最大数值。这个约束条件在后面的函数-sizeWithFont中将会用到。在-sizeWithFont中我们设置为 UILineBreakModeWordWrap来获取在允许自动换行的情况和上面提到的约束条件下正确的大小。最后我们使用MAX宏设置cell的高度,并且保证cell 的高度不会小于44个像素,因为它返回size.height和44两个数中的最大值。最后,我们将上下的页边空白考虑进去得到最后的结果。
为了使得读者形象化的了解页边空白,下面一个截图可以看出有一个边界环绕着label。调用[[label layer] setBorderWidth:2.0f]可以显示该边界从而方便我们看到页边空白。 计算并设置UILabel框大小
在前面我们用来计算高度的方法也是我们用来设置UILabel框大小的方法。下面将-cellForRowAtIndexPath代码补充完整:
1 |
- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath |
要注意if(cell == nil)模块是初始化代码,只在cell创建的时候运行一次。该模块外部代码每次都会执行只要在每次数据更新或者窗口拖拽之后调用了-cellForRowAtIndexPath。
也就是说,每次都需要设置label中文本内容以及设置label外框大小。注意如果label处于未初始化状态,我们需要通过调用[cell viewWithTag:1]来获取UILabel的句柄。这段代码跟前面计算高度的代码基本相同。
总结
动态计算单元格cell的高度真的并不困难。如果你有一个很复杂的cell,你只需要根据内容宽度和特定文本字体的大小来确定cell的高度。如果你不清楚你的外框显示在什么地方,只需要通过调用[[view layer] setBorderWidth:2.0f]来使外框显示即可。这会有助于你了解绘图过程以及更快地在更深的层次理解绘图显示的问题。
演示工程文件:DynamicHeights Demo Project
作者:Matt Long 原文链接:http://www.cimgf.com/2009/09/23/uitableviewcell-dynamic-height/
iOS-动态调整UITableViewCell的高度的更多相关文章
- iOS学习之路十三(动态调整UITableViewCell的高度)
大概你第一眼看来,动态调整高度是一件不容易的事情,而且打算解决它的第一个想法往往是不正确的.在这篇文章中我将展示如何使图表单元格的高度能根据里面文本内容来动态改变,同时又不必子类化UITableVie ...
- 动态调整UITableViewCell高度的实现方法
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPa ...
- iOS开发——Autolayout下动态调整单元格高度
情景描述: 有时候我们希望更新某一个单元格的数据,通常的做法是使用reloadData方法更新整个单元格.但是对一些情况是不适用的或者说实现起来比较麻烦.比如说这种简单的"点开"一 ...
- 让tableView的高度等于contentSize的高度、动态调整tableView的高度、tableView的高度自适应布局
文章概要: 1.简介下,tableView中的内容如何高度自适应的布局 2.如何做到让tableView的高度动态调整 还是看图作文吧- 首先,tableView的高度就是用户能够看见里面更大世界的那 ...
- [转] iOS TableViewCell 动态调整高度
原文: http://blog.csdn.net/crayondeng/article/details/8899577 最近遇到了一个cell高度变化的问题,在找解决办法的时候,参考了这篇文章,觉得不 ...
- 转:动态计算UITableViewCell高度详解
转自:http://www.cocoachina.com/industry/20140604/8668.html 不知道大家有没有发现,在iOS APP开发过程中,UITableView是我们显示 ...
- 动态计算UITableViewCell高度详解 (转)
感觉挺有用的一篇文章,分析了4种解决方案.回头测试之.如果有别的方案,我会在后面补上. 原文地址:http://www.ifun.cc/blog/2014/02/21/dong-tai-ji-suan ...
- 动态计算UITableViewCell高度
动态计算UITableViewCell高度 UILabel in UITableViewCell Auto Layout - UILabel的属性Lines设为了0表示显示多行.Auto Layout ...
- Android - 动态调整ListView高度
布局中,如果设计ListView的高度为包裹内容,那么ListView的高度是随着它的子条目的数量的变化而改变的, 这就可能会导致ListView下面的一些控件的位置也会随着ListView的高度的变 ...
随机推荐
- form表单 无法提交js动态添加的表单元素问题。。
第一种情况, 这种情况js动态添加的表单元素是不能提交到服务器端的 <table> <form method="post" action=" url ...
- PAT1023. Have Fun with Numbers
//水题,但是考点不水,可能用的strlen属于string库,但是只能用于字符,不能用数字,因为\0就是0.出现0无法判断,其次二倍时有可能有进位 //第一次在二倍进位上出了问题 #include& ...
- openstack4j接口调试
//import java.util.List;////import org.openstack4j.api.OSClient.OSClientV3;//import org.openstack4j. ...
- 网络设备模拟器 GNS3
https://www.gns3.com/support/docs/linux-installation sudo dpkg --add-architecture i386 sudo add-apt- ...
- WF4 常用类<第二篇>
一.WorkflowInvoker 常用方法如下: 方法 说明 BeginInvoke() 使用指定的 AsyncCallback 和用户提供的状态以异步方式调用工作流 EndInvoke() 返回使 ...
- IE CSS HACK
IE 属性值 HACK .test { background:blue; /*所有浏览器*/ background:yellow\9; /*所有IE浏览器*/ background:green\0; ...
- Eclipse Egit 安装
help->Install new software-> 在 work within 中输入以下网址 安装地址: http://download.eclipse.org/egit/upda ...
- MySQL查询昨天、今天、7天、近30天、本月、上一月数据
文章同步发表在博主网站朗度云,传输门:http://www.wolfbe.com/detail/201608/291.html 在开发或者统计时,我们可能需要统计某个表的数据.比如:查看今天新增的 ...
- asp.net mvc 用Redis实现分布式集群共享Session。
1.这两天研究Redis搞分布式session问题,网上找的资料都是用ServiceStack.Redis来实现的,但是在做性能测试的时候发现最新的v4版本有限制每小时候最多请求6000次,因为官网开 ...
- LevelDB:一个快速轻量级的key-value存储库(译)
作者:Jeff Dean, Sanjay Ghemawat 原文:http://leveldb.googlecode.com/svn/trunk/doc/index.html 译者:phylips@b ...