美文网首页
tableView动态行高

tableView动态行高

作者: 时间在改变 | 来源:发表于2017-07-14 15:35 被阅读0次

    目录

    手写代码和IB处理tableView动态行高

    手写代码情况下,需要考虑的方面:

    一、label单行与多行的区别

    二、手写label背景填充跟着字来是否麻烦?

    三、单行情况下,文字带中文,设置行间距,计算出的高度不准确。

    备注


    tableView是我们常用的控件之一,我们来谈一谈对于其行高的动态设置。

    手写代码:

    [string boundingRectWithSize:size options:NSStringDrawingUsesLineFragmentOrigin attributes:attributes context:nil].size

    IB:

    设定位置,不设定固定高,editor中设置sizeToFit,在heightForRow方法中给cell赋值后调用layoutIfNeeded方法。

    (若想背景填充跟着字来,设置label的width的less than最大宽度,字数不足一行的,约束也会自动缩到与label长度匹配)

    由于heightForRow会调用多次,在heightForRow中给cell赋值和调用layoutIfNeeded,性能会比较差。

    解决方案:

    1、根据id缓存每行的高度

    2、设置预估行高

    方案1、减少了调用cell赋值和layoutIfNeeded,性能相对提升。但是在获取行高的方法里进行了cell的赋值,结构上不合理。

    方案2、在固定行高的情况下合适,动态行高的情况由于预估行高和实际行高的不同会出现列表跳动。这样说来,在固定行高的情况下设置预估行高能减少heightForRow的调用,提升性能。

    手写和IB的区别:

    手写:仅仅是计算;

    IB:程序一启动就会全部加载进内存由系统托管,先强制布局然后看占了多大的尺寸。

    使用手写代码的时候,有些东西需要考虑一下:

    一、label单行与多行的区别

    使用NSStringDrawingUsesLineFragmentOrigin

    官方文档的描述:

    To correctly draw and size multi-line text, pass NSStringDrawingUsesLineFragmentOrigin in the options parameter.

    多行文本draw或者获取高度,需要有NSStringDrawingUsesLineFragmentOrigin在options参数中

    我看到有不少人使用了NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading

    不明白为什么要这样使用?先看看官方文档对两个选项的描述:

    NSStringDrawingUsesLineFragmentOrigin

    The specified origin is the line fragment origin, not the base line origin

    指定的原点是行片段的原点, 而不是基线原点。

    NSStringDrawingUsesFontLeading

    Uses the font leading for calculating line heights

    使用字体行距计算行高。

    我看到文章有提出

    1、NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading这种能解决有时高度不准的问题

    2、在textView中,显示行数是10行,使用NSStringDrawingUsesLineFragmentOrigin时只计算出了5行的高度,而使用NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading计算出了10行的高度

    针对这两个情况:

    1、目前我使用中文、英文和中英文混合,使用NSStringDrawingUsesLineFragmentOrigin和使用NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading的效果一样。

    2、我通过UIFont获取字高度,textView显示了多少行,算出这几行的高度,然后这些文字通过boundingRectWithSize:options: attributes: context:方法计算一下高度,发现使用NSStringDrawingUsesLineFragmentOrigin没问题。

    UIFont中找到了两个属性:ascender、capHeight。第一个可以得到中文字体的实际显示大小,第二个可以得到英文字母和数字的实际显示大小

    这样看来使用要不要NSStringDrawingUsesFontLeading都一样,如果有不同的意见,请在下方评论。

    二、刚刚看IB背景填充跟着字数来好像很简单,那么手写label背景填充跟着字来是否麻烦?

    使用attributedText即可,好像也不麻烦。

    三、单行情况下,文字带中文,设置行间距,计算出的高度不准确。

    那么看看我们需要先确定的判断条件:

    1、是否设置行间距;

    2、是否是单行;

    3、是否带中文;

    那么如果满足这三种情况的话,我将size高度中的lineSpacing减掉不就可以了,那么看代码

    这个时候运行后会发现还是有问题,size对了,但是label设置attributedText时带了lineSpacing,字的显示不对,那么我需要将attributedText中的lineSpacing也去掉。

    这个时候没问题了。以上方法都放在NSString+Private文件中。

    备注:

    官方文档:

    This method returns fractional sizes (in the size component of the returned CGRect); to use a returned size to size views, you must raise its value to the nearest higher integer using the ceil function.

    获取的CGRect的值用一下ceil方法

    相关文章

      网友评论

          本文标题:tableView动态行高

          本文链接:https://www.haomeiwen.com/subject/qhtghxtx.html