UITableViewcell autolayout下动态高度
项目中最经常使用的一个UI就是UITableView了。iOS7、8进一步优化了复用机制,用起来相当爽。配合Autolayout,适配工作减轻了非常多。
曾经做适配工作都是在heightForRow里边先计算出来Cell的高度。然后再CellForRow写适配代码。工作量尽管不是非常大,可是非常繁琐。
相对于这样的写法,假设减去计算height这步,工作量自然降低非常多。首先给出一种我媳妇给提供的方法,这是她做聊天UI时因为过度计算而怒创的方法
,当时我看到就震惊了,之后我就一直用这种方法
。
f=watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvR3Jvd2luZ0dpYW50/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center.jpg" alt="">
使用这中方法就可以省反复计算frame的操作,计算一次布局就可以。
如今IOS7、8都出来这么久了,autolayout也炒的非常热。如今看了下确实方便了非常多。比我在iOS6方便多了。
前两天看了下autolayout,如今结合tableviewcell试试效果。看了几个demo,发现iOS7跟iOS8不一样,iOS8更加简单。
第一、iOS7 tableviewcell + autolayout
使用storyboard简单创建一个project。并加入例如以下约束(不熟悉约束加入方法的可參考我之前的博客autolayout)

关联project文件,Cell连线,复用标识符等(不熟悉。可參考我之前的博客):
f=watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvR3Jvd2luZ0dpYW50/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center.jpg" alt="">

重头戏来了,代码中改怎样改动:
cellForRow依旧是我们之前的写法,赋值:
<span style="color:#993399;">- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
TestCell *cell = [tableView dequeueReusableCellWithIdentifier:@"testCell" forIndexPath:indexPath];
NSLog(@"cell create...");
if (!cell) {
NSLog(@"cell is nil!");
}
cell.ts_label.text = self.data[indexPath.row];
return cell;
}</span>
重点在于计算height,改动方法例如以下:
<span style="color:#993399;">- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
TestCell* cell = [tableView dequeueReusableCellWithIdentifier:@"testCell"]; cell.ts_label.text = self.data[indexPath.row];
CGSize size = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
NSLog(@"size = %@ %lf",NSStringFromCGSize(size), cell.ts_label.preferredMaxLayoutWidth
); return size.height + 1;
}
</span>
有三点须要注意:
第一点:不要在heightForRow使用
- (id)dequeueReusableCellWithIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath
你会发现进入了死循环。heightForRow->cellforRow->hei...Row
第二点:使用systemLayoutSizeFittingSize,他会依据约束条件算出来新的size,(所以约束条件一定要准确,非常多BUG都是由于约束有问题)
它有两种參数:
UIKIT_EXTERN const CGSize UILayoutFittingCompressedSize NS_AVAILABLE_IOS(6_0);//紧凑,大小适中的最小尺寸
UIKIT_EXTERN const CGSize UILayoutFittingExpandedSize NS_AVAILABLE_IOS(6_0);//宽松
第三点:新的size计算的是contentview的size,Cell.size.height = content view.size.height+1,记得加上一个切割线的高度。
好的到这里看看执行效果:

咋一看感觉效果实现了,细致观察发现label的高度算的不正确。第三行label不仅仅有三行,所以这个size算的不准。
经过研究发现,这个时候须要给label一个宽度值,这样才干算出来所须要的高度。
能够设置label的这个属性来固定宽度。
// Support for constraint-based layout (auto layout)
// If nonzero, this is used when determining -intrinsicContentSize for multiline labels
@property(nonatomic) CGFloat preferredMaxLayoutWidth NS_AVAILABLE_IOS(6_0);
我们改动heightForRow的方法:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
TestCell* cell = [tableView dequeueReusableCellWithIdentifier:@"testCell"];
cell.ts_label.preferredMaxLayoutWidth = 260;
cell.ts_label.text = self.data[indexPath.row];
CGSize size = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
NSLog(@"size = %@ %lf",NSStringFromCGSize(size), cell.ts_label.preferredMaxLayoutWidth
); return size.height + 1;
}
跑起来看看效果:
f=watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvR3Jvd2luZ0dpYW50/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center.jpg" alt="">
这才像个样子,哇哈哈。
这个属性也能够在storyboard中设置:

第二、iOS8 tableviewcell + autolayout
iOS7的方法已经简单非常多了,只是iOS8更加简单:iOS8仅仅须要两行代码加上约束就可以完毕适配!
!
有木有非常夸张!!
看方法:
<span style="color:#993399;">- (void)viewDidLoad {
</span><span style="color:#663366;"> [super viewDidLoad];
self.data = @[@"hahahahahahahahahahahaha",@"gagagaga",@"lalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalala",@"wawawawawawawawawawawawawawawawawawawawa",@"papapapapapapapapapapapapapapapapapapapapapapapapapapapapapapapapapapapapapapapapapapapapapapapapapapapapapapapapapapapapapapapapapapapapapapapapapapapa",@""];
self.tableView.estimatedRowHeight = 120;
self.tableView.rowHeight = UITableViewAutomaticDimension;
}</span>
<span style="color:#663366;">- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
TestCell *cell = [tableView dequeueReusableCellWithIdentifier:@"testCell" forIndexPath:indexPath];
NSLog(@"cell create...");
if (!cell) {
NSLog(@"cell is nil!");
}
cell.ts_label.text = self.data[indexPath.row];
return cell;
}</span>
看到没有,iOS8设置都不须要heightForRow了。仅仅须要设置下预估高度
<span style="color:#663366;">estimatedRowHeight</span>
<span style="color:#663366;"></span><pre name="code" class="objc"><span style="color:#663366;">rowHeight = UITableViewAutomaticDimension</span>
iOS7优化了tableview,获取Cell高度不再是一次性所有载入heightForRow。然后再生成Cell。而是先调用:
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
等Cell真正要呈现的时候在调用heightForRow。
真实的效果呢

高端大气上档次啊,哇哈哈。
看看其它机型

哈哈,就是这么简单,Cell就是配好了!
!!
总结一下:iOS7须要注意preferredMaxLayoutWidth的设置,iOS8须要设置estimatedRowHeight、rowHeight = UITableViewAutomaticDimension。更加注意的是约束的准确!
!。
UITableViewcell autolayout下动态高度的更多相关文章
- iOS开发——使用Autolayout生成动态高度的TableViewCell单元格
步骤一.TableViewCell中使用Autolayout 要点:Cell的高度必须在Constraints中指明,但不能定死,需要让内部由内容决定高度的View决定动态高度. 如UILabel设置 ...
- iOS开发——Autolayout下动态调整单元格高度
情景描述: 有时候我们希望更新某一个单元格的数据,通常的做法是使用reloadData方法更新整个单元格.但是对一些情况是不适用的或者说实现起来比较麻烦.比如说这种简单的"点开"一 ...
- AutoLayout深入浅出五[UITableView动态高度]
本文转载至 http://grayluo.github.io//WeiFocusIo/autolayout/2015/02/01/autolayout5/ 我们经常会遇到UITableViewCell ...
- 使用Autolayout xib实现动态高度的TableViewCell
http://my.oschina.net/u/2360693/blog/481236?p={{totalPage}} 创建Xib文件 首先将Cell做好布局,调整到满意的位置和宽度,然后开始做Aut ...
- AutoLayout处理UITableView动态高度
我们经常会遇到UITableViewCell的高度要跟随内容而调整,在未引入AutoLayout之前,我们使用以下方法计算Label高度,然后heightForRowAtIndexPath中返回计算的 ...
- 实现一个在autolayout下有宽度约束后,自动确定高度的view
我曾经遇到过一个问题:需要实现一个自定义的label(类似于UILabel),同时需要兼顾UILabel的大小自适应的特性.这个label通常宽度是固定的,通过autolayout指定其宽度约束,但不 ...
- swift 版本 UItableViewCell的动态高度补足
用swift的朋友们很多都是从ios8开发了, 其中针对table cell高度自动计算的 UITableViewAutomaticDimension 异常好用,但好像只对uilabel对象有效 ...
- soui中,列表控件动态高度的使用注意
1.listview的模板template中,需要增加defHeight属性,即默认高度,同时,不能出现itemHeight属性,否则动态高度会失效 2.数据适配器中,重写getViewDesired ...
- AIX 环境下动态路由
IBM AIX v5.3操作系统环境下动态路由配置如下: 1,用命令lssrc -S routed和lssrc -S gated分别检查routed和gated子系统是是活动状态.如果这两个子系统为活 ...
随机推荐
- bugumongo--ConnectToMongoDB
连接MongoDB 在能够对MongDB进行操作之前,需要使用BuguConnection连接到MongoDB数据库.代码如下: BuguConnection conn = BuguConnectio ...
- Zookeeper安装和配置
Zookeeper的安装和配置,可以配置成单机模式.伪集群模式.集群模式. 参考http://coolxing.iteye.com/blog/1871009 一. 单机模式 (1)zookeeper下 ...
- UVa 221 (STL 离散化) Urban Elevations
题意: 作图为n个建筑物的俯视图,右图为从南向北看的正视图,按从左往右的顺序输出可见建筑物的标号. 分析: 题中已经说了,要么x相同,要么x相差足够大,不会出现精度问题. 给这n个建筑物从左往右排序, ...
- [swustoj 404] 最小代价树
最小代价树(0404) 问题描述 以下方法称为最小代价的字母树:给定一正整数序列,例如:4,1,2,3,在不改变数的位置的条件下把它们相加,并且用括号来标记每一次加法所得到的和. 例如:((4+1)+ ...
- WEB架构师成长之路-架构师都要懂哪些知识 转
Web架构师究竟都要学些什么?具备哪些能力呢?先网上查查架构师的大概的定义,参见架构师修炼之道这篇文章,写的还不错,再查查公司招聘Web架构师的要求. 总结起来大概有下面几点技能要求: 一. 架构师有 ...
- Azure 负载平衡器新分发模式
Yves Pitsch Azure 网络首席项目经理 Azure负载平衡器是一种第四层(TCP.UDP)类型的负载平衡器,它可以将传入流量分发到云服务中正常运行的服务实例上,或者分发到负载平衡器集内所 ...
- SqlServer中decimal(numeric )、float 和 real 数据类型的区别[转]
decimal(numeric ) 同义,用于精确存储数值 float 和 real 不能精确存储数值 decimal 数据类型最 ...
- 安装VS2015出现的bug,各位安装请注意
昨天微软发布了vs2015 迫不及待的下载下来安装体验了一把,但是机器上同时安装有vs2010.vs2012.vs2013 .安装完成后,因为公司项目需要开发,打开vs2012 ,有如下提示: 百度查 ...
- Project Euler 26 Reciprocal cycles
题意:求1到n中所有数的倒数中循环小数循环体最长的数 解法:如果一个数的质因子只有2和5,那么这个数的倒数一定不是一个循环小数.如果一个数含有质因子2或5,那么它的循环体和去掉质因子2和5之后的数的循 ...
- LA 6540 Fibonacci Tree
以前做过的题···重新做一遍之后怎么做怎么wa···后来GG了···第二天看不知道为啥A了···难道我失忆了? 题意:无向图,边有黑色和白色两种颜色,求是否存在一个生成树中白边的个数是斐波那契数. 解 ...