iOS中Cell约束--使用xib实现多label的自动约束--高度随内容自适应

made in 小蠢驴的配图

       说起iOS开发,很多人的印象就是-弄一个tableView,把数据全丢到上面展示,听起来好像很粗糙,不过仔细一想,确实展示数据内容的,用的tableView是最多的了吧,说到这里,今天的男一号-tableViewCell就要登场了。

      本文的主题是--tableViewCell的高度自适应,计算cell高度的方法确实有好几种,因为做cell的时候,比较简单的界面我都是直接拉xib,手动连接约束比较省事,所以今天就来探索一波-- 使用xib实现cell高度自适应的简单方法;

手动设置数据源,初始展示

如图,这是最简单的tableView了,只有两个label,没有任何其他的控件,在未做任何处理的情况下,我们发现,内容是会越界(跑的屏幕之外的),首先第一步,我们得先解决这个问题,至少让内容都在屏幕内展示;

通过试图-发现内容越界

-->探索:难道是因为,tableView的高度不够,比如高度只有44,内容就只能这样显示了吗? 

首先:改变tableViewCell的高度 

其次:设置内容行数_valueLabel.numberOfLines=0;

如图,发现内容还是越界了

怀疑:内容label的宽度 = 无穷大? 所以并不会换行

xib的约束展示

如图,我们知道label只要设置两条约束,宽和高都可以自动实现内容的自适应,但是,这里如果不设置宽(添加右侧约束 == 确定 宽),label的宽会无限大,无限跑到内容的外部去


添加右侧约束


约束报错

如图,添加完右侧约束之后,我们发现约束报错了,原因:两个label都没设置宽度,都是根据内容自动设定的,这样就会导致均无法确定两个的frame,所有约束报错


-->小tips:这里只有两个label,并且没设置宽度约束(如果竖直方法,就是高度约束),都根据内容显示的时候,才会报错,如果你比如左侧label的内容是固定的(比如都是“姓名”),直接添加一个宽度约束,就可以解决,或者,左侧不是label,而是其他可以确定frame的空间,比如Btn,imageView都不会出现上述问题! 因为:当我们没设置label的frame的时候,默认的frame就是根据内容自适应的,所以不能两个需要自适应的出现在一起;

-->不信邪的:约束报错的情况下测试:

两个label约束下的展示

如图,我们发现,内容确实会自动换行了,也都有显示了,也证明了我们设置宽度约束的思路是没错的

但是! --> keyLabel不见了,因为我们做的两个label都是自适应的,所以并无法确定他们的准确位置!


解决办法:手动计算valueLabel的高度,但是,设置的是父试图(valueView)的高度-->通过高度约束修改!

设置valueView的高度约束

如图,添加一个View的高度约束,我们打算实现:valueLabel直接在valueView上显示,然后直接设置valueView的frame

高度约束设置完成

-->接下去:计算label的高度-->内容高度计算公式:CGRect rect = [str boundingRectWithSize:CGSizeMake(BottomW,CGFLOAT_MAX)options:optionsattributes:attrDiccontext:nil];

第一步:先拿到当前View的宽度!

第二步:设置valueLabel的宽度!

第三步:计算内容高度!

第四步:设置valueView高度!


操作完成,发现值设置进来了
内容虽然有换行,但是valueLabel还是宽度越界了
如图:虽然content拿到了数据,但是label的宽度此时却没跟着改变

解决办法-->手动算keyLabelLabel的宽度!

思路:1.设置keyLabel的宽度约束;

           2.根据keyLabel的实际内容,算出具体宽度,修改宽度约束;

           3.右侧valueLabel不设置宽度约束,设置右侧约束 = 0,通过计算得到valueLabel的宽度;

约束设置图

如图,因为如果同一行,两个label都不设置宽度约束,由于label默认会根据内容自适应,两个不确定的约束 -->导致约束报错!所以暂定,左侧设置宽度约束,然后再根据实际内容,修改左侧的宽度,而右侧的宽度 = 屏幕宽 - 左侧宽度!

设置keyLabel的宽度约束
设置valueLabel的右侧约束

此时我们发现,由于左侧的label是有宽度约束的,所以右侧的label此时约束设置(添加右侧约束 = 0)并不会再报错了!

根据keyLabel的内容计算宽度

通过内容,计算keyLabel的宽度,同时设置到keyLabel的宽度约束上,更新约束;

随后,valueView由于自适应,其宽度就自动 = 屏幕宽度 - keyLabel的宽度,不需要我们再次设置;

展示的内容如上

此时我们发现,有部分内容,还是被遮住了,label并不会完全显示出所有的内容

修改:label的宽度稍微加一点

发生这种情况,是由于Xcode8.0之后,字体的长度计算有了些许改变,我们在设置宽度时,稍微加一点,就可以解决这个问题。

修改完的展示

此时,label相互之间的约束冲突就解决了~


接下去,就是设置tableViewCell的高度自适应的问题了;

xib的快捷设置方法:1.在xib中,设置 顶部 和 底部 约束之后;

                                  2.手动计算 高度 约束的值

                                  3.使用Xcode自动适应Cell高度的方法

value高度的计算
自动计算高度


最终结果

如图,我们发现,keyLabel的宽度跟随内容自适应,vauleLabel的宽度 随 keyLabel的宽度自适应,valueLabel的高度 随 内容自适应,cell的高度随内容自适应~

小tips-->如果设置完_tableView.rowHeight=UITableViewAutomaticDimension 之后,发现高度还是固定的,检查一下,是否有设置了 tableView的高度代理方法-->(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath,有的话将其注释掉~

简单Demo:Demo

推荐阅读更多精彩内容