iOS 富文本

常用属性

key value 说明
NSFontAttributeName UIFont对象 字体大小:默认Helvetica(Neue) 12
NSParagraphStyleAttributeName NSParagraphStyle对象 段落设置
NSForegroundColorAttributeName UIColor对象 字体颜色,默认blackColor
NSBackgroundColorAttributeName UIColor对象 背景色,默认nil(无背景色)
NSLigatureAttributeName 包含整数的NSNumber对象 连字符:默认为1:默认连接,0:不连接
NSKernAttributeName 包含浮点数的NSNumber对象 字符间距:默认0(禁用)
NSTrackingAttributeName 包含浮点数的NSNumber对象 修改默认跟踪的数量。0表示禁用跟踪。iOS14及以后系统可用。
NSStrikethroughStyleAttributeName 包含整数的NSNumber对象 删除线:默认0(无删除线)
NSUnderlineStyleAttributeName 包含整数的NSNumber对象 下划线:默认0(无下划线)
NSStrokeColorAttributeName UIColor对象 描边颜色:nil(和文字的 foregroundColor一致)
NSStrokeWidthAttributeName 包含浮点数的NSNumber对象 描边宽度:正值空心描边,负值实心描边,默认0(不描边)
NSShadowAttributeName NSShadow对象 文本阴影,默认为nil:无阴影
NSTextEffectAttributeName NSString对象 文字效果:默认nil(没有文字效果)
NSAttachmentAttributeName NSTextAttachment对象 附件(常用作图文混排) :默认nil(没有附件)
NSLinkAttributeName NSURL (优先) 或 NSString对象 链接
NSBaselineOffsetAttributeName 包含浮点数的NSNumber对象 基线偏移量,默认为0;正值向上偏移,负值向下偏移,默认0(不偏移)
NSUnderlineColorAttributeName UIColor对象 下划线颜色:默认nil(和文字的 foregroundColor一致)
NSStrikethroughColorAttributeName UIColor对象 删除线颜色:默认 nil(和文字的 foregroundColor一致)
NSObliquenessAttributeName 包含浮点数的NSNumber对象 字体倾斜 :正值向右倾斜,负值向左倾斜, 默认0(不倾斜)
NSExpansionAttributeName 包含浮点数的NSNumber对象 文本扁平化:正值横向拉伸,负值横向压缩,默认0(不拉伸)
NSWritingDirectionAttributeName 存储NSNumber类型的NSArray对象 书写方向。控制字符可以通过屏蔽NSWritingDirection和NSWritingDirectionFormatType值来获得。 LRE: NSWritingDirectionLeftToRight\NSWritingDirectionEmbedding, RLE: NSWritingDirectionRightToLeft\NSWritingDirectionEmbedding, LRO: NSWritingDirectionLeftToRight\NSWritingDirectionOverride, RLO: NSWritingDirectionRightToLeft\NSWritingDirectionOverride
NSVerticalGlyphFormAttributeName 包含整数的NSNumber对象 0表示水平文本。1表示垂直文本。如果没有指定,它可以遵循更高级别的垂直方向设置。目前在iOS上,它总是水平的。任何其他值的行为是未定义的。

示例

NSLigatureAttributeName-连字符
    UIFont *font = [UIFont fontWithName:@"futura" size:18];
    NSString *text = @"逗号前面的我是一个没有连字符样式的fl,逗号后面的你是一个带连字符样式的fl(你看后半句的汉字连字符样式好难体现出来哦)";
    NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
    [attributes setObject:font forKey:NSFontAttributeName];
    NSMutableAttributedString *att = [[NSMutableAttributedString alloc] initWithString:text attributes:attributes];
    // 设置文本前半句无连字符效果
    [att addAttribute:NSLigatureAttributeName value:[NSNumber numberWithInt:0] range:NSMakeRange(0, 19)];
       // 设置文本后半句有连字符效果
    [att addAttribute:NSLigatureAttributeName value:[NSNumber numberWithInt:1] range:NSMakeRange(19, text.length - 19)];
att.png
NSKernAttributeName - 字符间距

注意: 正值间距加宽,负值间距变窄,0表示默认效果

    UIFont *font = [UIFont fontWithName:@"futura" size:18];
    NSString *text = @"设置我的字间距为正值20有拉大效果,中间的你是正常效果,设置他的字间距为负值-5有减少效果";
    NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
    [attributes setObject:font forKey:NSFontAttributeName];
    NSMutableAttributedString *att = [[NSMutableAttributedString alloc] initWithString:text attributes:attributes];
    [att addAttribute:NSKernAttributeName value:@20 range:NSMakeRange(0, 18)];
    [att addAttribute:NSKernAttributeName value:@(-5) range:NSMakeRange(28, text.length - 28)];
att.png
文字描边

NSStrokeColorAttributeName - 描边颜色
NSStrokeWidthAttributeName - 描边宽度

  • 描边颜色要搭配非0的描边宽度才会生效,如果只设置了描边颜色,描边宽度为0,则没有描边效果
  • 描边宽度是正数,会对文字进行描边,但文字中心不填充( 一种经典的空心文本样式是在该值为3.0)
  • 描边宽度是负数,会对文字进行描边,而且会同时对文字中心进行填充(填充的颜色为文字本来的字体颜色)
    UIFont *font = [UIFont fontWithName:@"futura" size:18];
    NSString *text = @"只设置描边颜色,没有设置描边宽度(默认为0),没有效果";
    NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
    [attributes setObject:font forKey:NSFontAttributeName];
    NSMutableAttributedString *att = [[NSMutableAttributedString alloc] initWithString:text attributes:attributes];
    [att addAttribute:NSStrokeColorAttributeName value:[UIColor blueColor] range:NSMakeRange(0, text.length)];
att.png
    UIFont *font = [UIFont fontWithName:@"futura" size:18];
    NSString *text = @"将描边宽度设置为正数3,无描边颜色,具有空心效果哦,此时描边颜色默认成字体本来的颜色!";
    NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
    [attributes setObject:font forKey:NSFontAttributeName];
    NSMutableAttributedString *att = [[NSMutableAttributedString alloc] initWithString:text attributes:attributes];
    [att addAttribute:NSStrokeWidthAttributeName value:@(3) range:NSMakeRange(0, text.length)];
att.png
    UIFont *font = [UIFont fontWithName:@"futura" size:18];
    NSString *text = @"将描边宽度设置为正数3,描边颜色为红色,具有空心效果哦,因为正数不对文字内部进行填充!";
    NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
    [attributes setObject:font forKey:NSFontAttributeName];
    NSMutableAttributedString *att = [[NSMutableAttributedString alloc] initWithString:text attributes:attributes];
    [att addAttribute:NSStrokeColorAttributeName value:[UIColor redColor] range:NSMakeRange(0, text.length)];
    [att addAttribute:NSStrokeWidthAttributeName value:@(3) range:NSMakeRange(0, text.length)];
att.png
    UIFont *font = [UIFont fontWithName:@"futura" size:18];
    NSString *text = @"将描边宽度设置为负数-3,又设置描边颜色,无空心效果,因为负数会对文字内部进行填充!";
    NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
    [attributes setObject:font forKey:NSFontAttributeName];
    NSMutableAttributedString *att = [[NSMutableAttributedString alloc] initWithString:text attributes:attributes];
    [att addAttribute:NSStrokeColorAttributeName value:[UIColor purpleColor] range:NSMakeRange(0, text.length)];
    [att addAttribute:NSStrokeWidthAttributeName value:@(-3) range:NSMakeRange(0, text.length)];
att.png
NSShadowAttributeName-阴影
    UIFont *font = [UIFont fontWithName:@"futura" size:18];
    NSString *text = @"一个有阴影的文本!";
    NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
    [attributes setObject:font forKey:NSFontAttributeName];
    NSMutableAttributedString *att = [[NSMutableAttributedString alloc] initWithString:text attributes:attributes];
    // 创建NSShadow实例
    NSShadow *shadow = [[NSShadow alloc] init];
    shadow.shadowColor = [UIColor purpleColor];
    shadow.shadowBlurRadius = 3.0;
    shadow.shadowOffset = CGSizeMake(0, 0.8);
    // 添加属性
    [att addAttribute:NSShadowAttributeName value:shadow range:NSMakeRange(0, text.length)];
att.png
NSTextEffectAttributeName-文字效果
        UIFont *font = [UIFont fontWithName:@"futura" size:18];
    NSString *text = @"我是没有文字效果的,你是有文字效果的!";
    NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
    [attributes setObject:font forKey:NSFontAttributeName];
//    [attributes setObject:[UIColor darkGrayColor] forKey:NSBackgroundColorAttributeName];
    NSMutableAttributedString *att = [[NSMutableAttributedString alloc] initWithString:text attributes:attributes];
    [att addAttribute:NSTextEffectAttributeName value:NSTextEffectLetterpressStyle range:NSMakeRange(10, text.length - 10)];
att.png

att.png
NSLinkAttributeName - 链接

注意:UILabel无法使用该属性, 但UITextView 控件可以使用,所以下面关于 NSLinkAttributeName 属性的代码也是使用 UITextView 来测试的。

// 注意:跳转链接要实现UITextView的这个委托方法
- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)url inRange:(NSRange)characterRange {
   return YES;
}

- (void)linkAttributeTest {
   NSString *text = @"点我跳转到百度哦!";
   NSMutableAttributedString * attributeStr = [[NSMutableAttributedString alloc] initWithString:text];
   NSURL *url = [NSURL URLWithString:@"https://www.baidu.com"];
   [attributeStr addAttribute:NSLinkAttributeName value:url range:NSMakeRange(0, text.length)];
   self.textView.attributedText = attributeStr;
}
NSBaselineOffsetAttributeName-基准线

注意:正值向上偏移,负值向下偏移,默认0(不偏移)

    UIFont *font = [UIFont fontWithName:@"Savoye Let" size:18];
    NSString *text = @"负值向下偏移";
    NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
    [attributes setObject:font forKey:NSFontAttributeName];
    NSMutableAttributedString *att = [[NSMutableAttributedString alloc] initWithString:text attributes:attributes];
    [att addAttribute:NSBaselineOffsetAttributeName value:@(-10) range:NSMakeRange(0, text.length)];
att.png

att.png

att.png
NSExpansionAttributeName -文本扁平化(横向拉伸)

注意:正值横向拉伸,负值横向压缩,默认0(不拉伸)

    UIFont *font = [UIFont fontWithName:@"Savoye Let" size:18];
    NSString *text = @"正值横向拉伸,无扁平效果,负值横向压缩!";
    NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
    [attributes setObject:font forKey:NSFontAttributeName];
    NSMutableAttributedString *att = [[NSMutableAttributedString alloc] initWithString:text attributes:attributes];
    [att addAttribute:NSExpansionAttributeName value:@(0.8) range:NSMakeRange(0, 7)];
    [att addAttribute:NSExpansionAttributeName value:@(-0.8) range:NSMakeRange(13, text.length - 13)];
att.png
NSTrackingAttributeName

类似NSKernAttributeName。

UIFont *font = [UIFont fontWithName:@"Savoye Let" size:18];
    NSString *text = @"NSTrackingAttributeName,NSTrackingAttributeName,NSTrackingAttributeName";
    NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
    [attributes setObject:font forKey:NSFontAttributeName];
    NSMutableAttributedString *att = [[NSMutableAttributedString alloc] initWithString:text attributes:attributes];
    [att addAttribute:NSTrackingAttributeName value:@(8.8) range:NSMakeRange(0, 23)];
    [att addAttribute:NSTrackingAttributeName value:@(-8.8) range:NSMakeRange(46, 23)];
att.png

段落设置

NSMutableParagraphStyle
属性 说明
lineSpacing 行间距
paragraphSpacing 段落间距
alignment 对齐方式
firstLineHeadIndent 首行缩进
headIndent 整段缩进
tailIndent 右侧缩进
lineBreakMode 截断方式
minimumLineHeight 最小行高
maximumLineHeight 最大行高
baseWritingDirection 书写方向
lineHeightMultiple 行间距倍数
paragraphSpacingBefore 段首行空白空间
hyphenationFactor 连字属性 在iOS,唯一支持的值分别为0和1
tabStops 制表符
allowsDefaultTighteningForTruncation 收缩字符间距允许截断
    UIFont *font = [UIFont fontWithName:@"Savoye Let" size:18];
    NSString *text = @"段落\n右对齐\n行间距20";
    NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc]init];
    style.lineBreakMode = NSLineBreakByWordWrapping;
    style.alignment = NSTextAlignmentRight;
    style.lineSpacing = 20;
    NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
    [attributes setObject:style forKey:NSParagraphStyleAttributeName];
    [attributes setObject:font forKey:NSFontAttributeName];
    NSAttributedString *att = [[NSAttributedString alloc] initWithString:text attributes:attributes];
att.png

不同大小的字体对齐

默认基线对齐。iOS UIFont简介与文本行数判断

居中原理.jpg
    UIFont *font = [UIFont systemFontOfSize:21];
    UIFont *font2 = [UIFont systemFontOfSize:14];
    NSString *text = @"1😄不同大小的字体底部对齐😄样式(默认)\n2😄不同大小的字体顶部对齐😄样式\n3😄不同大小的字体中间对齐😄样式";
    NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
    [attributes setObject:font forKey:NSFontAttributeName];
    NSMutableAttributedString *att = [[NSMutableAttributedString alloc] initWithString:text attributes:attributes];
    [att addAttribute:NSFontAttributeName value:font2 range:NSMakeRange(10, 6)];
    [att addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(10, 6)];

    [att addAttribute:NSFontAttributeName value:font2 range:NSMakeRange(33, 6)];
    [att addAttribute:NSForegroundColorAttributeName value:[UIColor blueColor] range:NSMakeRange(33, 6)];
    [att addAttribute:NSBaselineOffsetAttributeName value:@(font.ascender - font2.ascender) range:NSMakeRange(33, 6)];
    
    [att addAttribute:NSFontAttributeName value:font2 range:NSMakeRange(52, 6)];
    [att addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(52, 6)];
    [att addAttribute:NSBaselineOffsetAttributeName value:@((font.lineHeight - font2.lineHeight)/2 + ((font.descender - font2.descender))) range:NSMakeRange(52, 6)];
att.png

图片

图片
    UIFont *font = [UIFont systemFontOfSize:24];
    NSString *text = @"富文本图片";
    NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
    [attributes setObject:font forKey:NSFontAttributeName];
    [attributes setObject:[UIColor yellowColor] forKey:NSBackgroundColorAttributeName];
    NSMutableAttributedString *att = [[NSMutableAttributedString alloc] initWithString:text attributes:attributes];
    NSLog(@"纯文字:%ld",att.length);
    NSTextAttachment *attachment = [[NSTextAttachment alloc] init];
    attachment.image = [UIImage imageNamed:@"1"];
    attachment.bounds = CGRectMake(0,0,30,20);
    [att appendAttributedString:[NSAttributedString attributedStringWithAttachment:attachment]];
    NSLog(@"文字+图片:%ld",att.length);

att.png
图片长度
    UIFont *font = [UIFont systemFontOfSize:24];
    NSString *text = @"富文本图片";
    NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
    [attributes setObject:font forKey:NSFontAttributeName];
    [attributes setObject:[UIColor yellowColor] forKey:NSBackgroundColorAttributeName];
    NSMutableAttributedString *att = [[NSMutableAttributedString alloc] initWithString:text attributes:attributes];
    NSLog(@"纯文字:%ld",att.length);
    NSTextAttachment *attachment = [[NSTextAttachment alloc] init];
    attachment.image = nil;
    attachment.bounds = CGRectMake(0,0,30,20);
    [att appendAttributedString:[NSAttributedString attributedStringWithAttachment:attachment]];
    NSLog(@"文字+图片:%ld",att.length);
att.png
纯文字:5
文字+图片:6

图片添加至NSTextAttachment生成富文本后,占一个字节长度(无论图片大小或是否存在)。

图片对齐

NSTextAttachment默认也是基线对齐,attachment.bounds的坐标原点Y轴是和基线持平,是CoreGraphics的坐标系。
原理同上述文字对齐。

    UIFont *font = [UIFont systemFontOfSize:24];
    NSString *text = @"富文本图片";
    NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
    [attributes setObject:font forKey:NSFontAttributeName];
    [attributes setObject:[UIColor yellowColor] forKey:NSBackgroundColorAttributeName];
    NSMutableAttributedString *att = [[NSMutableAttributedString alloc] initWithString:text attributes:attributes];
    NSLog(@"纯文字:%ld",att.length);
    NSTextAttachment *attachment = [[NSTextAttachment alloc] init];
    attachment.image = [UIImage imageNamed:@"1"];
    attachment.bounds = CGRectMake(0,0,30,20);
    [att appendAttributedString:[NSAttributedString attributedStringWithAttachment:attachment]];
    [att addAttribute:NSBaselineOffsetAttributeName value:@((font.lineHeight - 20)/2 + (font.descender)) range:NSMakeRange(5, 1)];
    NSLog(@"文字+图片:%ld",att.length);
att.png
    UIFont *font = [UIFont systemFontOfSize:24];
    NSString *text = @"文本\n富文本图片\n文本";
    NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
    [attributes setObject:font forKey:NSFontAttributeName];
    [attributes setObject:[UIColor yellowColor] forKey:NSBackgroundColorAttributeName];
    NSMutableAttributedString *att = [[NSMutableAttributedString alloc] initWithString:text attributes:attributes];
    NSLog(@"纯文字:%ld",att.length);
    NSTextAttachment *attachment = [[NSTextAttachment alloc] init];
    attachment.image = [UIImage imageNamed:@"1"];
    attachment.bounds = CGRectMake(0,0,30,20);
    NSAttributedString *textAtt = [NSAttributedString attributedStringWithAttachment:attachment];
    [att insertAttributedString:textAtt atIndex:6];
    [att addAttribute:NSBaselineOffsetAttributeName value:@((font.lineHeight - 20)/2 + (font.descender)) range:NSMakeRange(6, 1)];
    NSLog(@"文字+图片:%ld",att.length);
att.png
文字图片间隔

NSKernAttributeName属性对图片与文字的间距设置不生效。

网络图片

判断网络图片是否存在,不存在先试用占位图,开启异步下载,下载完成后重新生成富文本替换。

参考文档

iOS富文本NSAttributedString垂直对齐
iOS--NSAttributedString超全属性详解及应用(富文本、图文混排)

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,636评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,890评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,680评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,766评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,665评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,045评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,515评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,182评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,334评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,274评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,319评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,002评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,599评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,675评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,917评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,309评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,885评论 2 341

推荐阅读更多精彩内容