一、关于AttributedString
在iOS开发过程中系统简单的封装工具已经不够我们使用,为了更好的开发,苹果公司为开发者提供了一套丰富的API供开发者们使用。其中开发过程中使用最多的就是AttributedString了吧,AttributedString与NSString类似,在iOS中AttributedString也分为NSAttributedString和NSMutableAttributedString,不同的是,AttributedString对象多了一个Attribute的概念,一个AttributedString的对象包含很多的属性,每一个属性都有其对应的字符区域,使用NSRange来进行描述。下面简单讲解一下AttributedString的属性及用法。
官方学习链接Attributed String Programming Guide
- 1.方式一:
首先初始化一个NSMutableAttributedString,然后向里面添加文字样式,最后将它赋给控件的AttributedText,该方法适合于文本较少而又需要分段精细控制的情况。
NSMutableAttributedString * attrStr = [[NSMutableAttributedString alloc] initWithString:@"我是第一种方式,哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈"];
[attrStr addAttribute: NSFontAttributeName value: [UIFont fontWithName: @"Papyrus" size: 15] range: NSMakeRange(0, attrStr.length)];
NSMutableParagraphStyle * style = [[NSMutableParagraphStyle alloc] init];
style.lineSpacing = 5.0;
[attrStr addAttribute: NSParagraphStyleAttributeName value: style range: NSMakeRange(0, attrStr.length)];
self.firstLabel.attributedText = attrStr;
- 2.方式二:
首先创建属性字典,初始化各种属性,然后和需要控制的文本一起创建并赋值给控件的AttributedText,该方法适合于需要控制的文本较多整体控制的情况,通常是从文件中读取的大段文本控制。
//第二种方式
NSDictionary * dict = @{NSFontAttributeName:[UIFont fontWithName: @"Papyrus" size: 15], [UIFont fontWithName: @"Papyrus" size: 15]:style };
NSMutableAttributedString * attrStr2 = [[NSMutableAttributedString alloc] initWithString:@"我是第二种方式,哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈" attributes:dict];
self.secondLabel.attributedText = attrStr2;
二 、 AttributedString究竟可以设置哪些属性
- NSFontAttributeName
设置字体属性,默认值:字体:Helvetica(Neue) 字号:12
获取系统的字体:[UIFont familyNames]
NSMutableAttributedString * attrStr = [[NSMutableAttributedString alloc] initWithString:@"我是NSFontAttributeName 字体:Papyrus 字号:15"];
[attrStr addAttribute: NSFontAttributeName value: [UIFont fontWithName: @"Papyrus" size: 15] range: NSMakeRange(0, attrStr.length)];
- NSParagraphStyleAttributeName(后面具体讲解)
该属性所对应的值是一个 NSParagraphStyle/NSMutableParagraphStyle 对象。该属性在一段文本上应用多个属性。
NSMutableParagraphStyle * style = [[NSMutableParagraphStyle alloc] init];
style.lineSpacing = 10.0;
NSMutableAttributedString * attrStr = [[NSMutableAttributedString alloc] initWithString:@"我是NSParagraphStyleAttributeName \\\\\\\\\\\\\\\\n行间距 10"];
[attrStr addAttribute: NSParagraphStyleAttributeName value: style range: NSMakeRange(0, attrStr.length)];
- NSForegroundColorAttributeName
设置字体颜色,取值为 UIColor对象,默认值为黑色
NSMutableAttributedString * attrStr = [[NSMutableAttributedString alloc] initWithString:@"我是NSForegroundColorAttributeName 颜色orangeColor"];
[attrStr addAttribute: NSForegroundColorAttributeName value: [UIColor orangeColor] range: NSMakeRange(0, attrStr.length)];
- NSBackgroundColorAttributeName
设置字体所在区域背景颜色,取值为 UIColor对象,默认值为nil, 透明色
NSMutableAttributedString * attrStr = [[NSMutableAttributedString alloc] initWithString:@"我是NSBackgroundColorAttributeName 背景颜色red"];
[attrStr addAttribute: NSBackgroundColorAttributeName value: [UIColor redColor] range: NSMakeRange(0, attrStr.length)];
- NSLigatureAttributeName
设置连体属性,取值为NSNumber 对象(整数),0 表示没有连体字符,1 表示使用默认的连体字符。2 表示使用所有连体符号。默认值为 1(注意,iOS 不支持值为 2)如下图'f' 'l'的连接
NSMutableAttributedString * attrStr = [[NSMutableAttributedString alloc] initWithString:@"我是NSLigatureAttributeName 'fl' 连体属性 0"];
[attrStr addAttribute: NSFontAttributeName value: [UIFont fontWithName: @"PingFang SC" size: 15] range: NSMakeRange(0, attrStr.length)];
[attrStr addAttribute: NSLigatureAttributeName value: @(0) range: NSMakeRange(0, attrStr.length)];
- NSKernAttributeName
设定字符间距,取值为 NSNumber 对象(整数),正值间距加宽,负值间距变窄。
NSMutableAttributedString * attrStr = [[NSMutableAttributedString alloc] initWithString:@"我是NSKernAttributeName 字符间距 2"];
[attrStr addAttribute: NSKernAttributeName value: @(2) range: NSMakeRange(0, attrStr.length)];
- NSStrikethroughStyleAttributeName
设置删除线,取值为 NSNumber 对象(整数)
NSMutableAttributedString * attrStr = [[NSMutableAttributedString alloc] initWithString:@"我是NSStrikethroughStyleAttributeName 删除线 1"];
[attrStr addAttribute: NSStrikethroughStyleAttributeName value: @(1) range: NSMakeRange(0, attrStr.length)];
- NSUnderlineStyleAttributeName
设置下划线,取值为 NSNumber 对象(整数),枚举常量 NSUnderlineStyle中的值。默认值是NSUnderlineStyleNone。
- NSStrokeColorAttributeName
设置填充颜色。取值为 UIColor 对象,需要和NSStrokeWidthAttributeName设置描边宽度,这样就能使文字产生镂空效果。
NSMutableAttributedString * attrStr = [[NSMutableAttributedString alloc] initWithString:@"我是NSStrokeColorAttributeName 配合NSStrokeWidthAttributeName使用"];
[attrStr addAttribute: NSStrokeColorAttributeName value: [UIColor redColor] range: NSMakeRange(0, attrStr.length)];
[attrStr addAttribute: NSStrokeWidthAttributeName value: @(2) range: NSMakeRange(0, attrStr.length)];
- NSStrokeWidthAttributeName
设置笔画宽度,取值为 NSNumber 对象(整数),负值填充效果,正值中空效果。与NSStrokeColorAttributeName配合使用
NSMutableAttributedString * attrStr = [[NSMutableAttributedString alloc] initWithString:@"我是NSStrokeWidthAttributeName 配合NSStrokeColorAttributeName使用"];
[attrStr addAttribute: NSStrokeWidthAttributeName value: @(-2) range: NSMakeRange(0, attrStr.length)];
[attrStr addAttribute: NSStrokeColorAttributeName value: [UIColor blueColor] range: NSMakeRange(0, attrStr.length)];
- NSShadowAttributeName
设置阴影属性,取值为 NSShadow 对象。默认为 nil。
NSMutableAttributedString * attrStr = [[NSMutableAttributedString alloc] initWithString:@"我是NSShadowAttributeName 竖直方向偏移 15"];
NSShadow * shadow = [[NSShadow alloc] init];
shadow.shadowColor = [UIColor grayColor];
shadow.shadowOffset = CGSizeMake(0, 15);
[attrStr addAttribute: NSShadowAttributeName value:shadow range: NSMakeRange(0, attrStr.length)];
- NSTextEffectAttributeName
设置文本特殊效果,取值为 NSString 对象,目前只有图版印刷效果可用NSTextEffectLetterpressStyle。
NSMutableAttributedString * attrStr = [[NSMutableAttributedString alloc] initWithString:@"我是NSTextEffectAttributeName 模式NSTextEffectLetterpressStyle"];
[attrStr addAttribute: NSTextEffectAttributeName value:NSTextEffectLetterpressStyle range: NSMakeRange(0, attrStr.length)];
- NSAttachmentAttributeName
设置文本附件,取值为NSTextAttachment对象,常用于文字图片混排
NSMutableAttributedString * attrStr = [[NSMutableAttributedString alloc] initWithString:@"我是NSAttachmentAttributeName "];
NSTextAttachment * textAtt = [[NSTextAttachment alloc] init];
textAtt.image = [UIImage imageNamed:@"tag_d"];
textAtt.bounds = CGRectMake(0, 0, 44, 44);
NSAttributedString *attrStr2 = [NSAttributedString attributedStringWithAttachment: textAtt];
[attrStr insertAttributedString: attrStr2 atIndex: 6];
- NSLinkAttributeName
设置链接属性,对象是NSURL点击后调用浏览器打开指定URL地址
推荐一款非常好用的轮子 TTTAttributedLabel
UITextView *textView = [[UITextView alloc] init];
textView.scrollEnabled = NO;
textView.editable = NO;
textView.frame =cell.bounds;
textView.textContainer.lineFragmentPadding = 0;
textView.textContainerInset = UIEdgeInsetsMake(0, 0, 0, 0);
textView.delegate = self;
attrStr = [[NSMutableAttributedString alloc] initWithString:@"我是NSLinkAttributeName 测试 百度"];
[attrStr addAttribute: NSLinkAttributeName value:[NSURL URLWithString: @"http://www.baidu.com"] range: NSMakeRange(0, attrStr.length)];
textView.attributedText = attrStr;
- NSBaselineOffsetAttributeName
设置基线偏移值,取值为 NSNumber (float),正值上偏,负值下偏
NSAttributedString *attrStr = [[NSMutableAttributedString alloc] initWithString:@"我是NSBaselineOffsetAttributeName 偏移5"];
[attrStr addAttribute: NSBaselineOffsetAttributeName value: @(5) range: NSMakeRange(0, attrStr.length)];
- NSUnderlineColorAttributeName
设置下划线颜色,取值为 UIColor 对象,默认值为黑色
NSAttributedString *attrStr = [[NSMutableAttributedString alloc] initWithString:@"我是NSUnderlineColorAttributeName "];
[attrStr addAttribute: NSUnderlineStyleAttributeName value:@(NSUnderlineStyleSingle) range: NSMakeRange(0, attrStr.length)];
[attrStr addAttribute: NSUnderlineColorAttributeName value:[UIColor yellowColor] range: NSMakeRange(0, attrStr.length)];
- NSStrikethroughColorAttributeName
设置删除线颜色,取值为 UIColor 对象,默认值为黑色
NSAttributedString *attrStr = [[NSMutableAttributedString alloc] initWithString:@"我是NSStrikethroughColorAttributeName "];
[attrStr addAttribute: NSStrikethroughStyleAttributeName value:@(1) range: NSMakeRange(0, attrStr.length)];
[attrStr addAttribute: NSStrikethroughColorAttributeName value:[UIColor brownColor] range: NSMakeRange(0, attrStr.length)];
- NSObliquenessAttributeName
设置字形倾斜度,取值为 NSNumber (float),正值右倾,负值左倾
NSAttributedString *attrStr = [[NSMutableAttributedString alloc] initWithString:@"我是NSStrikethroughColorAttributeName 右倾斜"];
[attrStr addAttribute: NSObliquenessAttributeName value:@(1) range: NSMakeRange(0, attrStr.length)];
- NSExpansionAttributeName
设置文本横向拉伸属性,取值为 NSNumber (float),正值横向拉伸文本,负值横向压缩
NSAttributedString *attrStr = [[NSMutableAttributedString alloc] initWithString:@"我是NSExpansionAttributeName 横向压"];
[attrStr addAttribute: NSFontAttributeName value: [UIFont fontWithName: @"Papyrus" size: 12] range: NSMakeRange(0, attrStr.length)];
[attrStr addAttribute: NSExpansionAttributeName value:@(1) range: NSMakeRange(0, attrStr.length)];
- NSWritingDirectionAttributeName
设置文字书写方向,取值为以下组合
@[@(NSWritingDirectionLeftToRight|NSWritingDirectionEmbedding)];
@[@(NSWritingDirectionRightToLeft|NSWritingDirectionEmbedding)];
@[@(NSWritingDirectionLeftToRight|NSWritingDirectionOverride)];
@[@(NSWritingDirectionRightToLeft|NSWritingDirectionOverride)];
NSAttributedString *attrStr = [[NSMutableAttributedString alloc] initWithString:@"我是NSWritingDirectionAttributeName 方式NSWritingDirectionLeftToRight&Embedding"];
[attrStr addAttribute: NSWritingDirectionAttributeName value:@[@(NSWritingDirectionLeftToRight | NSWritingDirectionEmbedding)] range: NSMakeRange(0, attrStr.length)];
- NSVerticalGlyphFormAttributeName
文本方向,取值为 NSNumber 对象(整数)。0 表示横排文本。1 表示竖排文本。在 iOS 中,总是使用横排文本,0 以外的值都未定义。
NSAttributedString *attrStr = [[NSMutableAttributedString alloc] initWithString:@"我是NSVerticalGlyphFormAttributeName "];
[attrStr addAttribute: NSVerticalGlyphFormAttributeName value:@(0) range: NSMakeRange(0, attrStr.length)];
- NSDocumentTypeDocumentAttribute
直接进行 html 的展示
NSString * htmlString = @"<html><body> Some html string \n <font size=\"13\" color=\"red\">This is some text!This is some text!This is some text!This is some text!This is some text!</font> </body></html>";
attrStr = [[NSMutableAttributedString alloc] initWithData:[htmlString dataUsingEncoding:NSUnicodeStringEncoding] options:@{ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType } documentAttributes:nil error:nil];
三、关于计算
1 .在7.0以后官方计算的API
- (CGRect)boundingRectWithSize:(CGSize)size options:(NSStringDrawingOptions)options attributes:(nullable NSDictionary<NSString *, id> *)attributes context:(nullable NSStringDrawingContext *)context NS_AVAILABLE(10_11, 7_0);
参数
size:
宽高限制,用于计算文本绘制时占据的矩形块。
options:
文本绘制时的附加选项。可能取值请参考“NSStringDrawingOptions”。
attributes:
文本绘制时用到的AttributedString的属性,就是文中提到的20几种。
context:
context上下文。包括一些信息,例如如何调整字间距以及缩放。最终,该对象包含的信息将用于文本绘制。该参数一般为 nil 。
返回值:
一个矩形,大小等于文本绘制完将占据的宽和高。
具体计算方式,example
-(CGFloat)getSpaceLabelHeight:(NSString*)str withFont:(UIFont*)font withWidth:(CGFloat)width
{
NSMutableParagraphStyle *paraStyle = [[NSMutableParagraphStyle alloc] init];
paraStyle.alignment = NSTextAlignmentLeft;
paraStyle.lineSpacing = 4;
NSDictionary *dic = @{NSFontAttributeName:font, NSParagraphStyleAttributeName:paraStyle
};
CGSize size = [str boundingRectWithSize:CGSizeMake(width, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:dic context:nil].size;
return size.height;
}
2 .计算真实的大小,sizeThatFits
- (CGSize)sizeThatFits:(CGSize)size; // return 'best' size to fit given size. does not actually resize view. Default is return existing view size
3 . 自适应,sizeToFit
- (void)sizeToFit; // calls sizeThatFits: with current view bounds and changes bounds size.
视具体情况而定,灵活应用上面三种方式计算即可,满足绝大多数需求。
附:NSParagraphStyle的属性参考
属性 | 解读 |
---|---|
lineSpacing | CGFloat类型,行距 |
paragraphSpacing | CGFloat类型,段距 |
alignment | NSTextAlignment,对齐方式 |
firstLineHeadIndent | CGFloat类型,首行缩进 |
headIndent | CGFloat类型,缩进 |
tailIndent | CGFloat类型,尾部缩进 |
lineBreakMode | CGFloat类型,断行方式 |
minimumLineHeight | CGFloat类型,最小行高 |
maximumLineHeight | CGFloat类型,最大行高 |
baseWritingDirection | NSWritingDirection,句子方向 |
lineHeightMultiple | CGFloat类型,可变行高,乘因数 |
paragraphSpacingBefore | CGFloat类型,段首空间 |
hyphenationFactor | CGFloat类型,连字符属性 |
照例放Demo,仅供参考
Demo地址:
https://github.com/yongliangP/AttributedStringDemo
如果你觉得对你有帮助请点喜欢哦,也可以关注我,每周至少一篇技术。
或者关注 我的专题 每周至少5篇更新,多谢支持哈。