iOS开发笔记常用工具之富文本属性介绍

前言

最近在项目中用到了图文混排的功能,研究了一下之后发现还挺好玩的,因此写一篇文章来记录一下其中的一些知识。

Apple提供了二十来种样式
UIKIT_EXTERN NSString * const NSFontAttributeName NS_AVAILABLE(10_0, 6_0);                // UIFont, default Helvetica(Neue) 12
UIKIT_EXTERN NSString * const NSParagraphStyleAttributeName NS_AVAILABLE(10_0, 6_0);      // NSParagraphStyle, default defaultParagraphStyle
UIKIT_EXTERN NSString * const NSForegroundColorAttributeName NS_AVAILABLE(10_0, 6_0);     // UIColor, default blackColor
UIKIT_EXTERN NSString * const NSBackgroundColorAttributeName NS_AVAILABLE(10_0, 6_0);     // UIColor, default nil: no background
UIKIT_EXTERN NSString * const NSLigatureAttributeName NS_AVAILABLE(10_0, 6_0);            // NSNumber containing integer, default 1: default ligatures, 0: no ligatures
UIKIT_EXTERN NSString * const NSKernAttributeName NS_AVAILABLE(10_0, 6_0);                // NSNumber containing floating point value, in points; amount to modify default kerning. 0 means kerning is disabled.
UIKIT_EXTERN NSString * const NSStrikethroughStyleAttributeName NS_AVAILABLE(10_0, 6_0);  // NSNumber containing integer, default 0: no strikethrough
UIKIT_EXTERN NSString * const NSUnderlineStyleAttributeName NS_AVAILABLE(10_0, 6_0);      // NSNumber containing integer, default 0: no underline
UIKIT_EXTERN NSString * const NSStrokeColorAttributeName NS_AVAILABLE(10_0, 6_0);         // UIColor, default nil: same as foreground color
UIKIT_EXTERN NSString * const NSStrokeWidthAttributeName NS_AVAILABLE(10_0, 6_0);         // NSNumber containing floating point value, in percent of font point size, default 0: no stroke; positive for stroke alone, negative for stroke and fill (a typical value for outlined text would be 3.0)
UIKIT_EXTERN NSString * const NSShadowAttributeName NS_AVAILABLE(10_0, 6_0);              // NSShadow, default nil: no shadow
UIKIT_EXTERN NSString *const NSTextEffectAttributeName NS_AVAILABLE(10_10, 7_0);          // NSString, default nil: no text effect

UIKIT_EXTERN NSString * const NSAttachmentAttributeName NS_AVAILABLE(10_0, 7_0);          // NSTextAttachment, default nil
UIKIT_EXTERN NSString * const NSLinkAttributeName NS_AVAILABLE(10_0, 7_0);                // NSURL (preferred) or NSString
UIKIT_EXTERN NSString * const NSBaselineOffsetAttributeName NS_AVAILABLE(10_0, 7_0);      // NSNumber containing floating point value, in points; offset from baseline, default 0
UIKIT_EXTERN NSString * const NSUnderlineColorAttributeName NS_AVAILABLE(10_0, 7_0);      // UIColor, default nil: same as foreground color
UIKIT_EXTERN NSString * const NSStrikethroughColorAttributeName NS_AVAILABLE(10_0, 7_0);  // UIColor, default nil: same as foreground color
UIKIT_EXTERN NSString * const NSObliquenessAttributeName NS_AVAILABLE(10_0, 7_0);         // NSNumber containing floating point value; skew to be applied to glyphs, default 0: no skew
UIKIT_EXTERN NSString * const NSExpansionAttributeName NS_AVAILABLE(10_0, 7_0);           // NSNumber containing floating point value; log of expansion factor to be applied to glyphs, default 0: no expansion

UIKIT_EXTERN NSString * const NSWritingDirectionAttributeName NS_AVAILABLE(10_6, 7_0);    // NSArray of NSNumbers representing the nested levels of writing direction overrides as defined by Unicode LRE, RLE, LRO, and RLO characters.  The control characters can be obtained by masking NSWritingDirection and NSWritingDirectionFormatType values.  LRE: NSWritingDirectionLeftToRight|NSWritingDirectionEmbedding, RLE: NSWritingDirectionRightToLeft|NSWritingDirectionEmbedding, LRO: NSWritingDirectionLeftToRight|NSWritingDirectionOverride, RLO: NSWritingDirectionRightToLeft|NSWritingDirectionOverride,

UIKIT_EXTERN NSString * const NSVerticalGlyphFormAttributeName NS_AVAILABLE(10_7, 6_0);   // An NSNumber containing an integer value.  0 means horizontal text.  1 indicates vertical text.  If not specified, it could follow higher-level vertical orientation settings.  Currently on iOS, it's always horizontal.  The behavior for any other value is undefined.

可以看到最低支持版本包括了iOS6和iOS7,所以不用担心版本兼容问题。

好了部分介绍下(实际开发中视情况使用)
首先定义了一些测试用的字符串和一个UILabel
static NSString *const kTestString1 = @"测试字符串1";
static NSString *const kTestString2 = @"测试字符串段落1\n测试字符串段落2";
static NSString *const kTestString3 = @"I am ForKid";

-(UILabel *)testLabel{
    if (!_testLabel) {
        _testLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 0, kWidth - 20, kHeight)];
        _testLabel.backgroundColor = [UIColor lightGrayColor];
        _testLabel.numberOfLines = 0;
        _testLabel.font = [UIFont boldSystemFontOfSize:50.f];
    }
    return _testLabel;
}
1.文字字体NSFontAttributeName:这个用来设置文字的字体Font,这个大家都会使用的。
实例:
    NSRange range = NSMakeRange(0, kTestString1.length);
    NSMutableAttributedString *attributeString = [[NSMutableAttributedString alloc] initWithString:kTestString1];
    [attributeString addAttribute:NSFontAttributeName value:[UIFont boldSystemFontOfSize:40.f] range:range];
    self.testLabel.attributedText = attributeString;
运行效果:
字体.png
2.文字前景色NSForegroundColorAttributeName:这个其实就是文字的颜色
实例:
    NSRange range = NSMakeRange(0, kTestString1.length);
    NSMutableAttributedString *attributeString = [[NSMutableAttributedString alloc] initWithString:kTestString1];
    [attributeString addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:range];
    self.testLabel.attributedText = attributeString;
运行效果
文字前景色.png
3.文字背景色
实例:
    NSRange range = NSMakeRange(0, kTestString1.length);
    NSMutableAttributedString *attributeString = [[NSMutableAttributedString alloc] initWithString:kTestString1];
    [attributeString addAttribute:NSBackgroundColorAttributeName value:[UIColor redColor] range:range];
    self.testLabel.attributedText = attributeString;
运行效果
文字背景色.png
4.连字符NSLigatureAttributeName:这个一般情况下不会用到,没有做过多的测试,而且有些字体还不支持。
实例
    NSRange range = NSMakeRange(0, kTestString3.length);
    NSMutableAttributedString *attributeString = [[NSMutableAttributedString alloc] initWithString:kTestString3];
    //0无连体效果,1连体效果
    [attributeString addAttribute:NSLigatureAttributeName value:@(1) range:range];
    self.testLabel.attributedText = attributeString;
这个就没有运行图了
test.jpg
5.字符间距NSKernAttributeName:这个就是在渲染文字的时候文字于文字之间的间距,value是NSNumber类型。
实例:
    NSRange range = NSMakeRange(0, kTestString1.length);
    NSMutableAttributedString *attributeString = [[NSMutableAttributedString alloc] initWithString:kTestString1];
    [attributeString addAttribute:NSKernAttributeName value:@(20) range:range];
    self.testLabel.attributedText = attributeString;
运行效果:
字符间距.png
6.删除线NSStrikethroughStyleAttributeName:这个属性有点特殊,它分为两个样式:单删除线、双删除线。具体的显示根据设置的值来确定
实例
    NSRange range = NSMakeRange(0, kTestString1.length);
    NSMutableAttributedString *attributeString = [[NSMutableAttributedString alloc] initWithString:kTestString1];
    //1~7单线,依次加粗
    //9~15:双线,依次加粗
    [attributeString addAttribute:NSStrikethroughStyleAttributeName value:@(7) range:range];
    self.testLabel.attributedText = attributeString;
运行效果:
  • 单线


    删除线_单线.png
  • 双线


    删除线_双线.png
另外,还可以设置删除线的颜色NSStrikethroughColorAttributeName
实例
    NSRange range = NSMakeRange(0, kTestString1.length);
    NSMutableAttributedString *attributeString = [[NSMutableAttributedString alloc] initWithString:kTestString1];
    [attributeString addAttribute:NSStrikethroughStyleAttributeName value:@(7) range:range];
    [attributeString addAttribute:NSStrikethroughColorAttributeName value:[UIColor blueColor] range:range];
    self.testLabel.attributedText = attributeString;
运行效果
删除线颜色.png
7.下划线NSUnderlineStyleAttributeName:文字下划线,可以指定样式以及颜色。
实例:
    NSRange range = NSMakeRange(0, kTestString1.length);
    
    NSMutableAttributedString *attributeString = [[NSMutableAttributedString alloc] initWithString:kTestString1];
    //1~7单线,依次加粗
    //9~15:双线,依次加粗
    [attributeString addAttribute:NSUnderlineStyleAttributeName value:@(NSUnderlineStyleThick) range:range];
    [attributeString addAttribute:NSUnderlineColorAttributeName value:[UIColor redColor] range:range];
    self.testLabel.attributedText = attributeString;
运行效果:
下划线.png
tips:关于下划线具体的样式后续补充
8.镂空和描边NSStrokeColorAttributeNameNSStrokeWidthAttributeName:用于文字显示效果的文字边框线条粗细和颜色。
实例:
    NSRange range = NSMakeRange(0, kTestString1.length);
    NSMutableAttributedString *attributeString = [[NSMutableAttributedString alloc] initWithString:kTestString1];
    //正值镂空,负值描边
    [attributeString addAttribute:NSStrokeColorAttributeName value:[UIColor redColor] range:range];
    [attributeString addAttribute:NSStrokeWidthAttributeName value:@(2) range:range];
    self.testLabel.attributedText = attributeString;
运行效果
  • 镂空


    描边.png
  • 描边


    填充.png
9.阴影效果NSShadowAttributeName:给文字添加阴影效果。
实例:
    NSRange range = NSMakeRange(0, kTestString1.length);
    NSMutableAttributedString *attributeString = [[NSMutableAttributedString alloc] initWithString:kTestString1];

    NSShadow *shadow = [[NSShadow alloc] init];
    shadow.shadowOffset = CGSizeMake(5, 5);
    shadow.shadowColor = [UIColor redColor];
    shadow.shadowBlurRadius = 0;
    
    [attributeString addAttribute:NSShadowAttributeName value:shadow range:range];
    self.testLabel.attributedText = attributeString;
运行效果:
阴影效果.png
10.超链接NSLinkAttributeName:给文字添加一个超链接,并且显示效果会变成蓝色而且在文字下方添加下划线,想要点击的话如果是UITextView,需要在中实现相应的代理方法
- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange interaction:(UITextItemInteraction)interaction NS_AVAILABLE_IOS(10_0);

或者

- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange NS_DEPRECATED_IOS(7_0, 10_0, "Use textView:shouldInteractWithURL:inRange:forInteractionType: instead");

具体的实现内容我会在后面的文章中介绍

实例
    NSRange range = NSMakeRange(0, kTestString1.length);
    NSMutableAttributedString *attributeString = [[NSMutableAttributedString alloc] initWithString:kTestString1];
    [attributeString addAttribute:NSLinkAttributeName value:@"https://www.baidu.com" range:range];
    self.testLabel.attributedText = attributeString;
运行效果
超链接.png
11.基线偏移量NSBaselineOffsetAttributeName:这个是设置文字渲染时的偏移量。我还没怎么用到过,不过有一个情况可以使用,比如用于文档注释时的脚注
实例
    NSRange range = NSMakeRange(0, kTestString1.length);
    
    NSMutableAttributedString *attributeString = [[NSMutableAttributedString alloc] initWithString:kTestString1];
    [attributeString addAttribute:NSUnderlineStyleAttributeName value:@(2) range:range];
    [attributeString addAttribute:NSUnderlineColorAttributeName value:[UIColor redColor] range:range];
    [attributeString addAttribute:NSBaselineOffsetAttributeName value:@(0) range:range];
    
    
    NSMutableAttributedString *attributeString2 = [[NSMutableAttributedString alloc] initWithString:@"偏移测试"];
    [attributeString2 addAttribute:NSUnderlineStyleAttributeName value:@(2) range:NSMakeRange(0, 4)];
    [attributeString2 addAttribute:NSUnderlineColorAttributeName value:[UIColor redColor] range:NSMakeRange(0, 4)];
    [attributeString2 addAttribute:NSBaselineOffsetAttributeName value:@(-20) range:NSMakeRange(0, 4)];
    
    [attributeString appendAttributedString:attributeString2];
    self.testLabel.font = [UIFont boldSystemFontOfSize:16.f];
    self.testLabel.attributedText = attributeString;
运行效果
基线偏移量.png
12.倾斜NSObliquenessAttributeName:这个一般很少用到。
实例
    NSRange range = NSMakeRange(0, kTestString1.length);
    
    NSMutableAttributedString *attributeString = [[NSMutableAttributedString alloc] initWithString:kTestString1];
    //正值右倾,负值左倾
    [attributeString addAttribute:NSObliquenessAttributeName value:@(1) range:range];
    self.testLabel.attributedText = attributeString;
运行效果
文字倾斜.png
13.拉伸NSExpansionAttributeName:拉伸字符,这个和字符间距是不一样的。
实例
    NSRange range = NSMakeRange(0, kTestString1.length);
    NSMutableAttributedString *attributeString = [[NSMutableAttributedString alloc] initWithString:kTestString1];
    [attributeString addAttribute:NSExpansionAttributeName value:@(1) range:range];
    self.testLabel.attributedText = attributeString;   
运行效果
字符拉伸.png
14.图文混排NSAttachmentAttributeName
实例
    NSMutableAttributedString *attributeString = [[NSMutableAttributedString alloc] initWithString:kTestString1];
    UIImage *image = [UIImage imageNamed:@"test.jpg"];
    
    //创建一个NSTextAttachement对象
    NSTextAttachment *attachment = [[NSTextAttachment alloc] init];
    attachment.image = image;
    CGFloat height = [kTestString1 sizeWithAttributes:@{NSFontAttributeName:[UIFont boldSystemFontOfSize:24.f]}].height;
    //如果宽度大于剩余的宽度 则会从另行开始
    attachment.bounds = CGRectMake(0, 0, height, height);

    NSAttributedString *att = [NSAttributedString attributedStringWithAttachment:attachment];
    //拼接到最后面
    [attributeString appendAttributedString:att];
    //放入指定位置
    [attributeString insertAttributedString:att atIndex:3];
    
    self.testLabel.font = [UIFont boldSystemFontOfSize:24.f];
    self.testLabel.attributedText = attributeString;
运行效果
图文混排.png
Tips:
1.关于图文混排这里只是一个小小的演示效果,一般情况下需求比这个多很多,我都会在后续的文章当中做出对应的演示和说明以及Demo。
2.后续我会对当前比较流行的混排框架:比如YYText、DTCoreText以及TYAttributedLabel等三方库的使用做出介绍。
3.另外现在很多时候会通过解析HTML数据来获取数据,或者直接解析一段HTML源码来渲染出对应的文本信息,我也会在后续文章中介绍到,包括用到的三方框架和工具以及部分原理。
4.最近项目中用到了文本富文本编辑器,完成之后,我会分享一下。
15.段落样式NSParagraphStyleAttributeName:关于段落样式,这里不做解释,我在另一篇文章当中有做介绍和基本使用方法。

以上就是开发中常用的对字符串处理的方式,本文对应的Demo可以点击这里下载.

如果您有任何问题或者好的建议欢迎留言评论指正。

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

推荐阅读更多精彩内容