iOS 使用 boundingRectWithSize: 计算
在使用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 = [[NSParagraphStyledefaultParagraphStyle] mutableCopy]; style.lineBreakMode =NSLineBreakByWordWrapping; style.alignment =NSTextAlignmentLeft;NSAttributedString*string = [[NSAttributedStringalloc]initWithString:text attributes:@{NSFontAttributeName:[UIFontsystemFontOfSize:16],NSParagraphStyleAttributeName:style}];CGSizesize = [string boundingRectWithSize:CGSizeMake(200.f, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeadingcontext:nil].size;NSLog(@" size = %@",NSStringFromCGSize(size));// 并不是高度计算不对,我估计是计算出来的数据是 小数,在应用到布局的时候稍微差一点点就不能保证按照计算时那样排列,所以为了确保布局按照我们计算的数据来,就在原来计算的基础上 取ceil值,再加1;CGFloatheight = 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;
测试正常:
CalculateHeightForUILabel.png
Demo地址:Demo github 地址