前言
最近在项目中用到了图文混排的功能,研究了一下之后发现还挺好玩的,因此写一篇文章来记录一下其中的一些知识。
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;
运行效果:
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;
运行效果
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;
运行效果
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;
这个就没有运行图了
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;
运行效果:
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;
运行效果:
-
单线
-
双线
另外,还可以设置删除线的颜色
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;
运行效果
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;
运行效果:
tips:关于下划线具体的样式后续补充
8.镂空和描边NSStrokeColorAttributeName
、NSStrokeWidthAttributeName
:用于文字显示效果的文字边框线条粗细和颜色。
实例:
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;
运行效果
-
镂空
-
描边
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;
运行效果:
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;
运行效果
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;
运行效果
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;
运行效果
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;
运行效果
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;
运行效果
Tips:
1.关于图文混排这里只是一个小小的演示效果,一般情况下需求比这个多很多,我都会在后续的文章当中做出对应的演示和说明以及Demo。
2.后续我会对当前比较流行的混排框架:比如YYText、DTCoreText以及TYAttributedLabel等三方库的使用做出介绍。
3.另外现在很多时候会通过解析HTML数据来获取数据,或者直接解析一段HTML源码来渲染出对应的文本信息,我也会在后续文章中介绍到,包括用到的三方框架和工具以及部分原理。
4.最近项目中用到了文本富文本编辑器,完成之后,我会分享一下。
15.段落样式NSParagraphStyleAttributeName
:关于段落样式,这里不做解释,我在另一篇文章当中有做介绍和基本使用方法。
以上就是开发中常用的对字符串处理的方式,本文对应的Demo可以点击这里下载.