[iOS 开发基础]- 动态计算cell行高

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[iOS 开发基础]- 动态计算cell行高相关的知识,希望对你有一定的参考价值。

参考技术A 这几天在网上搜寻技术文章时,上的文章总是很合胃口。于是就在上面注册了账号,上的文章都写的很精髓。这是我第一次在上面写文章,多少有点小紧张,文章写的哪里不好,或者哪里有问题,欢迎大家提出来,我会修正。好了这里就不继续瞎扯了,现在进入正题吧。

相信很多初级开发者们对于动态计算cell的行高都很头大,总是计算不好,导致各种问题。这里我就讲一下平时我是怎样计算行高的。有很多种方法,一种是通过约束来动态的计算行高,在《 UITableView自动计算cell高度并缓存,再也不用管高度啦! 》这篇文章里写的已经很详细了,这里就不详述了。还有一种是提前计算行高保存到模型中,这里先看一下效果图;

这样也实现了动态计算行高,每一个cell都返回不同的高度。具体操作是先将数据模型传入一个计算行高的模型当中,然保存这个模型到数据数组中。通过heightForRowAtIndexPath方法返回不同的行高。

当然单单这样笼统的说,相信大家也很难理解我在说什么,别急听我细细道来。

首先我们和往常一样险些数据模型,有头像,昵称,文章里容。

然后根据需求的布局,提前进行cell的行高计算,根据控件数量添加模型属性。

添加完成之后,要额外添加cell行高属性和数据模型数据。

这里我们就可以开始布局了,这里提前计算没个控件的frame,然后进行布局。

其实我们自定义cell 的时候,就是文字内容的不确定性,导致我们无法静精确的计算cell的行高。但是我们可以通过这个方法来计算文字的高度。

然后在我们写数据数组时,将数据模型传入计算模型当中,像这样

传入之后就可以返回行高了,在tableView的delegate的方法中返回不同的行高就行了。

之后在自定义cell的时候,将我们提前计算好的frame赋值给控件就可以了。

注意的是,Lable的文字大小要和提前计算好的大小一致

这样我们就完成动态的返回cell的行高了。

各位读者姥爷们,文章写的比较匆忙,哪里写的不好希望大家多多指点。

iOS 动态计算行高,宽等

UILabel有两个计算文字大小的方法:

1.针对对富文本计算NSAttributedString

- (CGRect)boundingRectWithSize:(CGSize)size options:(NSStringDrawingOptions)options attributes:(nullable NSDictionary*)attributes context:(nullable NSStringDrawingContext *)context NS_AVAILABLE(10_11, 7_0);

2.针对与普通文本计算NSString

- (CGRect)boundingRectWithSize:(CGSize)size options:(NSStringDrawingOptions)options context:(nullable NSStringDrawingContext *)context NS_AVAILABLE(10_11, 6_0);

 

对于这两个方法有相同的参数:

 

参数一:size表示计算文本的最大宽高(就是限制的最大高度、宽度),一般情况下我们设置最大的宽度、高度不限制CGSizeMake(getScreenWidth(), CGFLOAT_MAX),注意:限制的宽度不同,计算的高度结果也不同。

参数二: options表示计算的类型

NSStringDrawingUsesLineFragmentOrigin:绘制文本时使用 line fragement origin 而不是 baseline origin。一般使用这项。整个文本将以每行组成的矩形为单位计算整个文本的尺寸( The specified origin is the line fragment origin, not the base line origin)        

NSStringDrawingUsesFontLeading:根据字体计算高度,使用字体的行间距来计算文本占用的范围,即每一行的底部到下一行的底部的距离计算 ( Uses the font leading for calculating line heights  )

NSStringDrawingUsesDeviceMetrics:使用象形文字计算高度,将文字以图像符号计算文本占用范围,而不是以字符计算。也即是以每一个字体所占用的空间来计算文本范围  (Uses image glyph bounds instead of typographic bounds  )

NSStringDrawingTruncatesLastVisibleLine:如果NSStringDrawingUsesLineFragmentOrigin设置,这个选项没有用,当文本不能适合的放进指定的边界之内,则自动在最后一行添加省略符号。如果NSStringDrawingUsesLineFragmentOrigin没有设置,则该选项不生效  (Truncates and adds the ellipsis character to the last visible line if the text doesn‘t fit into the bounds specified. Ignored if NSStringDrawingUsesLineFragmentOrigin is not also set.  )

参数三:attributes 表示富文本的属性NSAttributedString.h比如字体、文字样式NSFontAttributeNameNSParagraphStyleAttributeName

参数四:NSStringDrawingContext
When stringDrawingContext=nil, it‘s equivalent of passing the default instance initialized with [[NSStringDrawingContext alloc] init] context
上下文,包括一些信息,例如如何调整字间距以及缩放。该参数一般可为 nil 。


问题:有时候计算文字的时候大小和实际的大小不一样?

解决办法1:检测字体和限制的宽度是否设置正确(楼主载在这里/(ㄒoㄒ)/~~)

解决办法2:可以设置NSStringDrawingOptions options = NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading;
(注意:swift中要写这样的组合是不支持的,点击这里查看解决方法www.jianshu.com/p/545f7f1d8741)

解决办法3:当你是把获得的高度来布局控件的View的高度的时候,需要把获得size = [string boundingRectWithSize:CGSizeMake(getScreenWidth(), CGFLOAT_MAX) options:options context:nil].size转化为ceilf(size.height)

解决办法4:由于这个方法计算字符串的大小的通过取得字符串的size来计算, 如果你计算的字符串中包含\n\r 这样的字符,也只会把它当成字符来计算。但是在显示的时候就是\n是转义字符,那么显示的计算的高度就不一样了,所以可以采用:计算的高度 = boundingRectWithSize计算出来的高度 + \n\r转义字符出现的个数 * 单行文本的高度。

扩展:

TextKit学习(四)通过boundingRectWithSize:options:attributes:context:计算文本尺寸:http://blog.csdn.net/jymn_chen/article/details/10949279

Text Kit学习(入门和进阶)http://www.cocoachina.com/industry/20131028/7250.html




以上是关于[iOS 开发基础]- 动态计算cell行高的主要内容,如果未能解决你的问题,请参考以下文章

iOS开发学习-如何优化tableview的使用

iOS开发总结-UITableView 自定义cell和动态计算cell的高度

ios开发 在cell中动态添加图片解决重复出现图层问题

iOS两行代码实现动态缓存 cell 的高度

iOS 动态计算行高,宽等

iOS开发小技巧--iOS8之后的cell自动计算高度