NSAttributedString

NSAttributedString对齐方式

Posted by 邹壮壮 on May 20, 2020

1.基础知识

字形描述集(Glyphs Metris):即字形的各个参数

Glyphs Metris

边框(Bounding Box):一个假想的边框,尽可能地容纳整个字形。

基线(Baseline):一条假想的参照线,以此为基础进行字形的渲染。一般来说是一条横线。

基础原点(Origin):基线上最左侧的点。

行间距(Leading):行与行之间的间距。

字间距(Kerning):字与字之间的距离,为了排版的美观,并不是所有的字形之间的距离都是一致的,但是这个基本步影响到我们的文字排版。

上行高度(Ascent)和下行高度(Decent):一个字形最高点和最低点到基线的距离,前者为正数,而后者为负数。当同一行内有不同字体的文字时,就取最大值作为相应的值。如下图,

Decent

红框高度既为当前行的行高,绿线为baseline,绿色到红框上部分为当前行的最大Ascent,绿线到黄线为当前行的最大Desent,而黄框的高即为行间距。由此可以得出:lineHeight = Ascent + Decent + Leading。要做到更完善的排版,还需要掌握段落排版(Paragragh Style)相关的知识。

iOS/OSX中用于描述富文本的类是NSAttributedString,顾名思义,它比NSString多了Attribute的概念。它可以包含很多属性,粗体,斜体,下划线,颜色,背景色等等,每个属性都有其对应的字符区域。在OSX上我们只需解析完毕相应的数据,准备好NSAttributedString即可,底层的绘制完全可以交给相应的控件完成。但是在iOS上就没有这么方便,想要绘制Attributed String就需要用到CoreText了。

2.NSAttributedString

NSAttributedString对象管理适用于字符串中单个字符或字符范围的字符串和关联的属性集(例如字体和字距)。NSAttributedString对象的默认字体是Helvetica 12点,可能与平台的默认系统字体不同。因此,您可能希望创建适用于您的应用程序的非默认属性的新字符串。您还可以使用NSParagraphStyle类及其子类NSMutableParagraphStyle来封装NSAttributedString类使用的段落或标尺属性。

属性及说明

key 说明
NSFontAttributeName 字体,value是UIFont对象
NSParagraphStyleAttributeName 绘图的风格(居中,换行模式,间距等诸多风格),value是NSParagraphStyle对象
NSForegroundColorAttributeName 文字颜色,value是UIColor对象
NSLigatureAttributeName 字符连体,value是NSNumber
NSKernAttributeName 字符间隔
NSStrikethroughStyleAttributeName 删除线,value是NSNumber
NSUnderlineStyleAttributeName 下划线,value是NSNumber
NSStrokeColorAttributeName 描绘边颜色,value是UIColor
NSStrokeWidthAttributeName 描边宽度,value是NSNumber
NSShadowAttributeName 阴影,value是NSShadow对象
NSTextEffectAttributeName 文字效果,value是NSString
NSAttachmentAttributeName 附属,value是NSTextAttachment 对象
NSLinkAttributeName 链接,value是NSURL or NSString
NSBaselineOffsetAttributeName 基础偏移量,value是NSNumber对象
NSStrikethroughColorAttributeName 删除线颜色,value是UIColor
NSObliquenessAttributeName 字体倾斜
NSExpansionAttributeName 字体扁平化
NSVerticalGlyphFormAttributeName 垂直或者水平,value是 NSNumber,0表示水平,1垂直

富文本段落排版格式属性说明

属性 说明
lineSpacing 字体的行间距
firstLineHeadIndent 首行缩进
alignment (两端对齐的)文本对齐方式:(左,中,右,两端对齐,自然)
lineBreakMode 结尾部分的内容以……方式省略 ( “…wxyz” ,”abcd…” ,”ab…yz”)
headIndent 整体缩进(首行除外)
minimumLineHeight 最低行高
maximumLineHeight 最大行高
paragraphSpacing 段与段之间的间距
paragraphSpacingBefore 段首行空白空间
baseWritingDirection 书写方向(一共三种)
hyphenationFactor 连字属性 在iOS,唯一支持的值分别为0和1

3.字体大小不同文本垂直居中

需要设置NSBaselineOffsetAttributeName属性,可以达到目的,注意descender是负值。

NSMutableParagraphStyle *ParagraphStyle =  [[NSMutableParagraphStyle alloc] init];
    ParagraphStyle.lineHeightMultiple = 1;
    ParagraphStyle.lineSpacing = 0;
    ParagraphStyle.paragraphSpacing = 0;
    ParagraphStyle.paragraphSpacingBefore = 0;
    //居中对齐
    CGFloat centerX = ([UIFont systemFontOfSize:80].lineHeight - [UIFont systemFontOfSize:30].lineHeight)/2 + (([UIFont systemFontOfSize:80].descender - [UIFont systemFontOfSize:30].descender));
   //顶部对齐
    CGFloat top = ([UIFont systemFontOfSize:80].lineHeight - [UIFont systemFontOfSize:20].lineHeight)/2 - ([UIFont systemFontOfSize:80].descender - [UIFont systemFontOfSize:20].descender)/2;
    NSDictionary *dic1 = @{NSFontAttributeName:[UIFont systemFontOfSize:30],
                          NSForegroundColorAttributeName:[UIColor blackColor],
                          NSBackgroundColorAttributeName:[UIColor yellowColor],
                          NSBaselineOffsetAttributeName:@(centerX),
                          NSParagraphStyleAttributeName:ParagraphStyle
                          };
    NSDictionary *dic2 = @{NSFontAttributeName:[UIFont systemFontOfSize:80],
                           NSForegroundColorAttributeName:[UIColor redColor],
                           NSBackgroundColorAttributeName:[UIColor yellowColor],
                           NSBaselineOffsetAttributeName:@0,
                           NSParagraphStyleAttributeName:ParagraphStyle
                           };
    
    NSDictionary *dic3 = @{NSFontAttributeName:[UIFont systemFontOfSize:20],
                           NSForegroundColorAttributeName:[UIColor blueColor],
                           NSBackgroundColorAttributeName:[UIColor yellowColor],
                           NSBaselineOffsetAttributeName:@(top),
                           NSParagraphStyleAttributeName:ParagraphStyle
                           };
    NSMutableAttributedString *attributeStr1 =  [[NSMutableAttributedString alloc] initWithString:@"¥" attributes:dic1];
    NSAttributedString *attributeStr2 =  [[NSAttributedString alloc] initWithString:@" 58" attributes:dic2];
    NSAttributedString *attributeStr3 =  [[NSAttributedString alloc] initWithString:@" .88" attributes:dic3];
    
    [attributeStr1 appendAttributedString:attributeStr2];
    [attributeStr1 appendAttributedString:attributeStr3];
    
    NSTextAttachment *attachment = [[NSTextAttachment alloc] init];
    attachment.image = [UIImage imageNamed:@"biaoqing.jpg"];
    attachment.bounds = CGRectMake(0,0,[UIFont systemFontOfSize:80].ascender,[UIFont systemFontOfSize:80].ascender);
    
    [attributeStr1 appendAttributedString:[NSAttributedString attributedStringWithAttachment:attachment]];
    
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 100, 300, 50)];
    label.attributedText = attributeStr1;
    label.backgroundColor = [UIColor redColor];
    [self.view addSubview:label];
    [label sizeToFit];

效果如下(图上画了线):

效果图

持续更新中……..