- 在使用boundingRectWithSize: 计算 UILabel 高度,显示出来后 Label 内容显示不全,这种情况怎么治呢?
Demo地址:Demo github 地址
- 分析后可能存在的两个原因:
-
1.使用boundingRectWithSize:计算时传入的相关属性与实际显示的 UILabel 属性不一致,例: @{NSFontAttributeName:[UIFont systemFontOfSize:16]},计算时传入的字体大小为16,实际显示的大小为17;这里字体只是个例子,明眼人都知道,可是往往忽略的还有 lineBreakMode ,alignment等等;
- 解决方法:使用 NSMutableParagraphStyle 设置相关属性
-
2.计算出来的 height 正好是排版后的高度大小,是 CGFloat 类型,在是在我们设置UIlabel/Cell 高度时,可能存在四舍五入等,最后存在的一点点误差使得 UILabel 显示不全,可能出现缺少一行,上下空白太多等情况;
- 解决方案:为了确保布局按照我们计算的数据来,可以使用ceil函数对计算的 Size 取整,再加1,确保 UILabel按照计算的高度完好的显示出来; 或者使用方法CGRectIntegral(CGRect rect) 对计算的 Rect 取整,在加1;
-
NSString *text = _datasource[indexPath.row];
// 段落设置与实际显示的 Label 属性一致 采用 NSMutableParagraphStyle 设置Nib 中 Label 的相关属性传入到 NSAttributeString 中计算;
NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
style.lineBreakMode = NSLineBreakByWordWrapping;
style.alignment = NSTextAlignmentLeft;
NSAttributedString *string = [[NSAttributedString alloc]initWithString:text attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:16], NSParagraphStyleAttributeName:style}];
CGSize size = [string boundingRectWithSize:CGSizeMake(200.f, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading context:nil].size;
NSLog(@" size = %@", NSStringFromCGSize(size));
// 并不是高度计算不对,我估计是计算出来的数据是 小数,在应用到布局的时候稍微差一点点就不能保证按照计算时那样排列,所以为了确保布局按照我们计算的数据来,就在原来计算的基础上 取ceil值,再加1;
CGFloat height = ceil(size.height) + 1;
还有一种方法,可以达到相同的效果。采用 UILabel 的 -sizeThatFits:方法;
UILabel *label = [[UILabel alloc]init];
label.numberOfLines = 0;
label.lineBreakMode = NSLineBreakByWordWrapping;
label.textAlignment = NSTextAlignmentLeft;
label.text = text;
label.font = [UIFont systemFontOfSize:16];
CGSize labelSize = [label sizeThatFits:CGSizeMake(200.f, MAXFLOAT)];
CGFloat height = ceil(labelSize.height) + 1;
测试正常:
Demo地址:Demo github 地址