0%

UILabel 计算文字高度以及行高相关

首先是计算文字高度(也可以计算宽度,一般很少用),分别是针对NSStringNSAttributedString两种:

1
2
[attr boundingRectWithSize:CGSizeMake(kBLScreenWidth - 10, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading context:nil]
[text boundingRectWithSize:CGSizeMake(kBLScreenWidth - 10, CGFLOAT_MAX) options:NSStringDrawingUsesFontLeading|NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName: [UIFont systemFontOfSize:15]} context:nil]

这里之前看许多博客说如果有换行符\n的时候,会忽略掉直接按照一个字符算,但是上面的结果在iOS 8+上面换行符是有计算进去的。这里对options参数解释:

  • NSStringDrawingUsesLineFragmentOrigin:整个文本将以每行组成的矩形为单位计算整个文本的尺寸
  • NSStringDrawingUsesFontLeading:使用字体的行间距来计算文本占用的范围,即每一行的底部到下一行的底部的距离计算
  • NSStringDrawingUsesDeviceMetrics:将文字以图像符号计算文本占用范围,而不是以字符计算。也即是以每一个字体所占用的空间来计算文本范围
  • NSStringDrawingTruncatesLastVisibleLine:当文本不能适合的放进指定的边界之内,则自动在最后一行添加省略符号。如果NSStringDrawingUsesLineFragmentOrigin没有设置,则该选项不生效

一般通过上面方式就可以计算出文字高度或宽度,下面再看一下行高和行间距,注意一下在iOS里面的行高和行间距关系如下:

lineHeight

其中上面部分为行高,下面部分为行间距,具体设置方式在NSAttributedString里面:

1
2
3
4
5
6
7
NSMutableParagraphStyle * para = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
CGFloat lheight = 30;
para.maximumLineHeight = lheight;
para.minimumLineHeight = lheight;
para.lineSpacing = 10;

NSAttributedString * attr = [[NSAttributedString alloc] initWithString:text attributes:@{NSFontAttributeName: font, NSParagraphStyleAttributeName: para}];

通过截图可以看到文字在行高中是靠底部的,一般如果要设计的话是希望文字居中,需要设置Attribute另一个参数
NSBaselineOffsetAttributeName,其中需要设置的值为:

1
2
CGFloat baseOffset = (lheight - font.lineHeight) / 4;
NSAttributedString * attr = [[NSAttributedString alloc] initWithString:text attributes:@{NSFontAttributeName: font, NSParagraphStyleAttributeName: para, NSBaselineOffsetAttributeName: @(baseOffset)}];

之后效果:

baseOffset

文字在行已经居中,至于其中的计算为什么是除以4而不是除以2,我也不知道。

通过上面的设置之后文字高度、行高以及间距都有明确的显示,就可以按照UI出的图严格设置,并且各平台都可以统一样式。已经测试过中文、英文、日语和韩文都是没问题。