前言
最近在項目中用到了圖文混排的功能,研究了一下之后發現還挺好玩的,因此寫一篇文章來記錄一下其中的一些知識。
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.鏤空和描邊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;
運行效果
-
鏤空
描邊.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可以點擊這里下載.