iOS 中计算字符串高度 - 换行样式问题

iOS开发中我们有时需要代码预先计算出字符串的宽高来进行特殊布局,在iOS7以后,计算字符串高度使用boundingRectWithSize方法,

  • 创建并设置label控件
UILabel *label = [UILabel new];
label.userInteractionEnabled = NO;
label.textAlignment = NSTextAlignmentCenter;
label.lineBreakMode = NSLineBreakByCharWrapping;
label.numberOfLines = 0;
  • 计算字符长度 (一个很长的字符串)
str = @"您邀请\"123\"、\"123\"、...... \"123\"、\"123\"、\"123\"加入了群";

NSDictionary *attributes = @{NSFontAttributeName:[UIFont systemFontOfSize:14.0]};
CGSize textRect = CGSizeMake([UIScreen mainScreen].bounds.size.width - 30, MAXFLOAT);
CGFloat textHeight = [str boundingRectWithSize:textRect
                                       options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading
                                    attributes:attributes
                                       context:nil].size.height;

Bug表现

上述的代码执行后就会出现高度计算的问题,实际的效果是显示的文本高度比计算出来的高度少很多,导致出现空白。
然而当我把文本内容全都换成中文以后却变正常了,这让人摸不着头脑。

文本换行样式

  • 以单词为单位换行
    label.lineBreakMode = NSLineBreakByWordWrapping;
    这种方式将会包含多种规则
  1. 英文单词会作为一个整体不会出现截断,比如world
  2. 数字,例如12345也会作为一个整体
  3. 各种符号不会出现在行的第一个位置,会将上一行的最后单词移动到下一行. 包括标点符号和其他符号。例如 ,。, - ' "" _ [ 等等;
  4. 还有很多规则,这些都是为了阅读起来方便;
  • 以字符为单位换行
    label.lineBreakMode = NSLineBreakByCharWrapping;
    这种方式就比较简单了,以单个字符为单位,如果一行显示不下则换到下一行,从左到右连续排版没有其他规则;

Bug分析

注意上面代码part1部分UILabel设置的是以字符NSLineBreakByCharWrapping为单位换行,而文本计算的时候没有指定换行方式,系统默认的换行方式是以单词换行,上面代码中的数字123和引号\"还有顿号都会被换行规则限定,所以以这种排版计算出来的高度会高很多才导致了这个bug

修正后改后的代码

NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineBreakMode = NSLineBreakByCharWrapping;
NSDictionary * attributes = @{
                              NSFontAttributeName:font,
                              NSParagraphStyleAttributeName: paragraphStyle
                              };
CGSize textRect = CGSizeMake([UIScreen mainScreen].bounds.size.width - 30, MAXFLOAT);
CGFloat textHeight = [str boundingRectWithSize:textRect
                                       options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading
                                    attributes:attributes
                                       context:nil].size.height;
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容