iOS - 富文本
iOS--NSAttributedString超全屬性詳解及應用(富文本、圖文混排)
ios項目中經常需要顯示一些帶有特殊樣式的文本,比如說帶有下劃線、刪除線、斜體、空心字體、背景色、陰影以及圖文混排(一種文字中夾雜圖片的顯示效果)。通常想要實現這些效果要使用到iOS的Foundation框架提供的NSAttributedString類,NSAttributedString類中有許多屬性,不同屬性對應不同的文本樣式。本文主要對這些屬性做一個解釋說明,并會結合實際代碼來應用它們。
1. NSAttributedString屬性概覽表
| NSFontAttributeName | UIFont對象 | 字體大小:默認Helvetica(Neue) 12 |
| NSParagraphStyleAttributeName | NSParagraphStyle對象 | 文本字、行間距,對齊等:默認defaultParagraphStyle |
| NSForegroundColorAttributeName | UIColor對象 | 字體顏色:默認blackColor |
| NSBackgroundColorAttributeName | UIColor對象 | 背景色:默認nil(無背景色) |
| NSLigatureAttributeName | 包含整數的NSNumber對象 | 連字符:ios中有0和1兩個值;0表示沒有連字符,而1是默認的連字符 |
| NSKernAttributeName | 包含浮點數的NSNumber對象 | 字符間距:默認0(禁用) |
| NSStrikethroughStyleAttributeName | 包含整數的NSNumber對象 | 刪除線:默認0(無刪除線) |
| NSUnderlineStyleAttributeName | 包含整數的NSNumber對象 | 下劃線:默認0(無下劃線) |
| NSStrikethroughColorAttributeName | UIColor對象 | 刪除線顏色:默認 nil(和文字的 foregroundColor一致) |
| NSUnderlineColorAttributeName | UIColor對象 | 下劃線顏色:默認nil(和文字的 foregroundColor一致) |
| NSStrokeColorAttributeName | UIColor對象 | 描邊顏色:nil(和文字的 foregroundColor一致) |
| NSStrokeWidthAttributeName | 包含浮點數的NSNumber對象 | 描邊寬度:正值空心描邊,負值實心描邊,默認0(不描邊) |
| NSShadowAttributeName | NSShadow對象 | 文本陰影:默認nil(沒有陰影) |
| NSTextEffectAttributeName | NSString對象 | 文字效果:默認nil(沒有文字效果) |
| NSAttachmentAttributeName | NSTextAttachment對象 | 附件(常用作圖文混排) :默認nil(沒有附件) |
| NSLinkAttributeName | NSURL (優先) 或 NSString對象 | 鏈接 |
| NSBaselineOffsetAttributeName | 包含浮點數的NSNumber對象 | 基礎偏移量:正值向上偏移,負值向下偏移,默認0(不偏移) |
| NSObliquenessAttributeName | 包含浮點數的NSNumber對象 | 字體傾斜 :正值向右傾斜,負值向左傾斜, 默認0(不傾斜) |
| NSExpansionAttributeName | 包含浮點數的NSNumber對象 | 文本扁平化:正值橫向拉伸,負值橫向壓縮,默認0(不拉伸) |
2. 屬性詳解及應用(圖文混排比較特殊,會在第 3 部分單獨說明)
NSMutableAttributedString 是 NSAttributedString 的子類,一般來說我比較習慣使用NSMutableAttributedString來實現富文本,本文的例子也是采用NSMutableAttributedString來實現的,與NSAttributedString實現效果相比并無優缺點之分,主要目的是講清楚這些屬性。
本文使用NSMutableAttributedString實現富文本,主要步驟分為以下三步,為避免下面解釋代碼時所添加的注釋不斷重復,特在此說明提前說明一下:
-
調用 - (instancetype)initWithString:(NSString *)str 方法來創建 NSMutableAttributedString 實例
-
調用 - (void)addAttribute:(NSString *)name value:(id)value range:(NSRange)range 方法添加所需的 Attribute 屬性,要注意range的范圍,所添加的屬性只對指定范圍內的文字有效
-
給 label 賦值 : label.attributedText = attributedString;
2.1 NSFontAttributeName —— 字體大小
代碼 :
- (void)fontAttributeNameTest {NSString *text = @"我是30號系統字體,你是15號Courier-BoldOblique字體";// 1.創建NSMutableAttributedString實例NSMutableAttributedString *fontAttributeNameStr = [[NSMutableAttributedString alloc]initWithString:text]; // 2.添加屬性 [fontAttributeNameStr addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:30] range:NSMakeRange(0, 9)]; [fontAttributeNameStr addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"Courier-BoldOblique" size:15] range:NSMakeRange(9, text.length - 9)]; // 3.給label賦值 self.label.attributedText = fontAttributeNameStr; }效果圖 :
NSFontAttributeName.png
2.2 NSParagraphStyleAttributeName —— 文本字、行間距,對齊等
代碼:
- (void)paragraphStyleAttributeNameTest {NSString *text = @"我是一個很長很長很長的文本,我的字間距是5,行間距是20,對齊方式為居中對齊。";NSMutableAttributedString *attributeStr = [[NSMutableAttributedString alloc]initWithString:text]; // 創建NSMutableParagraphStyle實例 NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; paragraphStyle.lineSpacing = 5; //字間距5 paragraphStyle.paragraphSpacing = 20; //行間距是20 paragraphStyle.alignment = NSTextAlignmentCenter; //對齊方式為居中對齊 [attributeStr addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, text.length)]; self.label.attributedText = attributeStr; }效果圖:
NSParagraphStyleAttributeName.png2.3 NSForegroundColorAttributeName —— 字體顏色
代碼:
- (void)foregroundColorAttributeNameTest {NSString *text = @"你好呀,我默認顏色是label的textColor,但是我現在要通過NSForegroundColorAttributeName屬性變成一個藍色了,看好嘍!";NSMutableAttributedString *attributeStr = [[NSMutableAttributedString alloc]initWithString:text]; [attributeStr addAttribute:NSForegroundColorAttributeName value:[UIColor blueColor] range:NSMakeRange(26, text.length - 26)]; self.label.attributedText = attributeStr; }效果圖:
NSForegroundColorAttributeName.png2.4 NSBackgroundColorAttributeName —— 背景色
代碼:
- (void)backgroundColorAttributeNameTest {NSString *text = @"我是一個紫色背景色的文本!";NSMutableAttributedString *attributeStr = [[NSMutableAttributedString alloc]initWithString:text]; [attributeStr addAttribute:NSBackgroundColorAttributeName value:[UIColor purpleColor] range:NSMakeRange(0, text.length)]; self.label.attributedText = attributeStr; }效果圖:
NSBackgroundColorAttributeName.png2.5 NSLigatureAttributeName —— 連字符
ios 中有 0 和 1 兩個值:0表示沒有連字符,而1是默認的連字符。(一般對連筆寫的英文有效, 中文即使設置了連字符也很難表現出來)。
代碼:
- (void)ligatureAttributeNameTest {NSString *text = @"逗號前面的我是一個沒有連字符樣式的fl,逗號后面的你是一個帶連字符樣式的fl(你看后半句的漢字連字符樣式好難體現出來哦)";NSMutableAttributedString *attributeStr = [[NSMutableAttributedString alloc]initWithString:text]; [attributeStr addAttribute:NSFontAttributeName value:[UIFont fontWithName: @"futura" size: 20] range:NSMakeRange(0, text.length)]; // 設置文本前半句無連字符效果 [attributeStr addAttribute:NSLigatureAttributeName value:[NSNumber numberWithInt:0] range:NSMakeRange(0, 19)]; // 設置文本后半句有連字符效果 [attributeStr addAttribute:NSLigatureAttributeName value:[NSNumber numberWithInt:1] range:NSMakeRange(19, text.length - 19)]; self.label.attributedText = attributeStr; }效果圖:
NSLigatureAttributeName.png2.6 NSKernAttributeName —— 字符間距
注意: 正值間距加寬,負值間距變窄,0表示默認效果
代碼:
- (void)kernAttributeNameTest {NSString *text = @"設置我的字間距為正值20有拉大效果,中間的你是正常效果,設置他的字間距為負值-5有減少效果";NSMutableAttributedString *attributeStr = [[NSMutableAttributedString alloc]initWithString:text]; [attributeStr addAttribute:NSKernAttributeName value:@20 range:NSMakeRange(0, 18)]; [attributeStr addAttribute:NSKernAttributeName value:@(-5) range:NSMakeRange(28, text.length - 28)]; self.label.attributedText = attributeStr; }效果圖:
NSKernAttributeName.png----------------------------寫在設置文本的刪除線和下劃線之前----------------------
刪除線和下劃線的區別就是:刪除線是在文字中間顯示,下劃線是在文字的底部顯示;除這一點外,設置的可選值是一樣的,都是NSUnderlineStyle的枚舉常量
NSUnderlineStyleNone = 0x00,NSUnderlineStyleSingle = 0x01,NSUnderlineStyleThick NS_ENUM_AVAILABLE(10_0, 7_0) = 0x02, NSUnderlineStyleDouble NS_ENUM_AVAILABLE(10_0, 7_0) = 0x09, NSUnderlinePatternSolid NS_ENUM_AVAILABLE(10_0, 7_0) = 0x0000, NSUnderlinePatternDot NS_ENUM_AVAILABLE(10_0, 7_0) = 0x0100, NSUnderlinePatternDash NS_ENUM_AVAILABLE(10_0, 7_0) = 0x0200, NSUnderlinePatternDashDot NS_ENUM_AVAILABLE(10_0, 7_0) = 0x0300, NSUnderlinePatternDashDotDot NS_ENUM_AVAILABLE(10_0, 7_0) = 0x0400, NSUnderlineByWord NS_ENUM_AVAILABLE(10_0, 7_0) = 0x8000在 2.7 中會對他們進行一個統一說明。
--------------------------------------------------------------------------------------------------
2.7 NSStrikethroughStyleAttributeName —— 刪除線NSStrikethroughColorAttributeName —— 刪除線顏色NSUnderlineStyleAttributeName —— 下劃線NSUnderlineColorAttributeName —— 下劃線顏色
代碼:
- (void)strikethroughStyleAndUnderlineStyleTest {NSArray *textArr = @[@"NSUnderlineStyleNone樣式", @"NSUnderlineStyleSingle樣式", @"NSUnderlineStyleThick樣式", @"NSUnderlineStyleDouble樣式"]; NSArray *colorArr = @[[UIColor blueColor], [UIColor redColor], [UIColor purpleColor], [UIColor whiteColor]]; NSMutableAttributedString *attributeStr = [[NSMutableAttributedString alloc] init]; //依次為每個字符串數組中的字符添加不同樣式和不同顏色的刪除線、下劃線 for (int i = 0; i < textArr.count; i++) { NSMutableAttributedString *singleAttributeStr = [[NSMutableAttributedString alloc]initWithString:textArr[i]]; //設置刪除線樣式 [singleAttributeStr addAttribute:NSStrikethroughStyleAttributeName value:@(i) range:NSMakeRange(0, ((NSString *)textArr[i]).length)]; //設置刪除線顏色 [singleAttributeStr addAttribute:NSStrikethroughColorAttributeName value:colorArr[i] range:NSMakeRange(0, ((NSString *)textArr[i]).length)]; //設置下劃線樣式 [singleAttributeStr addAttribute:NSUnderlineStyleAttributeName value:@(i) range:NSMakeRange(0, ((NSString *)textArr[i]).length)]; //設置下劃線顏色 [singleAttributeStr addAttribute:NSUnderlineColorAttributeName value:colorArr[i] range:NSMakeRange(0, ((NSString *)textArr[i]).length)]; [attributeStr appendAttributedString:singleAttributeStr]; } self.label.attributedText = attributeStr; }效果圖:
刪除線和下劃線.png2.8 NSStrokeColorAttributeName —— 描邊顏色NSStrokeWidthAttributeName —— 描邊寬度
注意事項:
- 描邊顏色要搭配非0的描邊寬度才會生效,如果只設置了描邊顏色,描邊寬度為0,則沒有描邊效果
- 描邊寬度是正數,會對文字進行描邊,但文字中心不填充( 一種經典的空心文本樣式是在該值為3.0)
- 描邊寬度是負數,會對文字進行描邊,而且會同時對文字中心進行填充(填充的顏色為文字本來的字體顏色)
代碼:
- (void)strokeTest {// 給第一個label只設置描邊顏色NSString *text1 = @"只設置描邊顏色,沒有設置描邊寬度(默認為0),沒有效果";NSMutableAttributedString *attributeStr1 = [[NSMutableAttributedString alloc] initWithString:text1 ]; [attributeStr1 addAttribute:NSStrokeColorAttributeName value:[UIColor blueColor] range:NSMakeRange(0, text1.length)]; self.label1.attributedText = attributeStr1; // 給第二個label設置描邊寬度為正數3,不設置描邊顏色 NSString *text2 = @"將描邊寬度設置為正數3,無描邊顏色,具有空心效果哦,此時描邊顏色默認成字體本來的顏色!"; NSMutableAttributedString *attributeStr2 = [[NSMutableAttributedString alloc] initWithString:text2 ]; [attributeStr2 addAttribute:NSStrokeWidthAttributeName value:@(3) range:NSMakeRange(0, text2.length)]; self.label2.attributedText = attributeStr2; // 給第三個label設置描邊寬度為正數3,描邊顏色為紅色 NSString *text3 = @"將描邊寬度設置為正數3,描邊顏色為紅色,具有空心效果哦,因為正數不對文字內部進行填充!"; NSMutableAttributedString *attributeStr3 = [[NSMutableAttributedString alloc] initWithString:text3 ]; [attributeStr3 addAttribute:NSStrokeColorAttributeName value:[UIColor redColor] range:NSMakeRange(0, text3.length)]; [attributeStr3 addAttribute:NSStrokeWidthAttributeName value:@(3) range:NSMakeRange(0, text3.length)]; self.label.attributedText = attributeStr3; // 給第四個label設置描邊寬度為負數-3,描邊顏色為紫色 NSString *text4 = @"將描邊寬度設置為負數-3,又設置描邊顏色,無空心效果,因為負數會對文字內部進行填充!"; NSMutableAttributedString *attributeStr4 = [[NSMutableAttributedString alloc] initWithString:text4 ]; [attributeStr4 addAttribute:NSStrokeColorAttributeName value:[UIColor purpleColor] range:NSMakeRange(0, text4.length)]; [attributeStr4 addAttribute:NSStrokeWidthAttributeName value:@(-3) range:NSMakeRange(0, text4.length)]; self.label3.attributedText = attributeStr4; }效果圖:
描邊.png2.9 NSShadowAttributeName —— 文本陰影
代碼:
- (void)shadowTest {NSString *text = @"一個有陰影的文本!";NSMutableAttributedString * attributeStr = [[NSMutableAttributedString alloc] initWithString:text]; // 創建NSShadow實例 NSShadow *shadow = [[NSShadow alloc] init]; shadow.shadowColor = [UIColor purpleColor]; shadow.shadowBlurRadius = 3.0; shadow.shadowOffset = CGSizeMake(0, 0.8); // 添加屬性 [attributeStr addAttribute:NSShadowAttributeName value:shadow range:NSMakeRange(0, text.length)]; self.label.attributedText = attributeStr; }效果圖:
NSShadowAttributeName.png2.10 NSTextEffectAttributeName —— 文字效果
代碼:
- (void)textEffectAttributeTest {NSString *text = @"我是沒有文字效果的,你是有文字效果的!";NSMutableAttributedString * attributeStr = [[NSMutableAttributedString alloc] initWithString:text]; [attributeStr addAttribute:NSTextEffectAttributeName value:NSTextEffectLetterpressStyle range:NSMakeRange(10, text.length - 10)]; self.label.attributedText = attributeStr; }效果圖:
NSTextEffectAttributeName.png2.11 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; }效果圖:
NSLinkAttributeName.png 點擊鏈接后的頁面.png2.12 NSBaselineOffsetAttributeName —— 基礎偏移量
注意:正值向上偏移,負值向下偏移,默認0(不偏移)
代碼:
- (void)baselineOffsetAttributeName {NSString *text = @"正值向上偏移,無偏移效果,負值向下偏移!";NSMutableAttributedString * attributeStr = [[NSMutableAttributedString alloc] initWithString:text]; [attributeStr addAttribute:NSBaselineOffsetAttributeName value:@(10) range:NSMakeRange(0, 7)]; [attributeStr addAttribute:NSBaselineOffsetAttributeName value:@(-10) range:NSMakeRange(13, text.length - 13)]; self.label3.attributedText = attributeStr; }效果圖:
NSBaselineOffsetAttributeName.png2.13 NSObliquenessAttributeName —— 字體傾斜
注意:正值向右傾斜,負值向左傾斜, 默認0(不傾斜)
代碼:
- (void)obliquenessTest {NSString *text = @"正值向右傾斜,無偏移效果,負值向左傾斜!";NSMutableAttributedString * attributeStr = [[NSMutableAttributedString alloc] initWithString:text]; [attributeStr addAttribute:NSObliquenessAttributeName value:@(1) range:NSMakeRange(0, 7)]; [attributeStr addAttribute:NSObliquenessAttributeName value:@(-1) range:NSMakeRange(13, text.length - 13)]; self.label.attributedText = attributeStr; }效果圖:
NSObliquenessAttributeName.png2.14 NSExpansionAttributeName —— 文本扁平化(橫向拉伸)
注意:正值橫向拉伸,負值橫向壓縮,默認0(不拉伸)
代碼:
- (void)expansionAttributeTest {NSString *text = @"正值橫向拉伸,無扁平效果,負值橫向壓縮!";NSMutableAttributedString * attributeStr = [[NSMutableAttributedString alloc] initWithString:text]; [attributeStr addAttribute:NSExpansionAttributeName value:@(0.8) range:NSMakeRange(0, 7)]; [attributeStr addAttribute:NSExpansionAttributeName value:@(-0.8) range:NSMakeRange(13, text.length - 13)]; self.label.attributedText = attributeStr; }效果圖:
NSExpansionAttributeName.png3. 圖文混排
應用場景:如果界面需要顯示一串從后臺拿到的一個文本,這個文本有長有短,要求文本后面要拼接一個圖片,而且如果文本長度為超過一行,圖片要跟在文本的最后面。此時就要求圖片似乎作為一個文本一樣,可以拼接在后臺拿到的文本后面。類似這樣的:
應用場景舉例:圖片在文字前面 應用場景舉例:圖片在文字中間 應用場景舉例:圖片在文字后面這樣的效果還是通過NSAttributedString類實現的。步驟:
- 參考代碼:
圖片在文字之后的調用方式:
- (void)initializeLabel:(UILabel *)label withText:(NSString *)text {// 傳健文本的attributedStringNSAttributedString *textAttributedString = [UILabel attributedStringWithText:text textColor:[UIColor blackColor] textFont:[UIFont systemFontOfSize:20] hasUnderlineStyle:NO lineSpacing:6 paragraphSpacing:16]; // 創建圖片的attributedString NSAttributedString *imageAttributedString = [UILabel attributedStringWithImage:[UIImage imageNamed:@"lovebook.png"] imageBounds:CGRectMake(0, -5, 109, 28)]; // 將文本和圖片的attributedString拼接成一個resultAttributedString NSAttributedString *resultAttributedString = [UILabel jointAttributedStringWithItems:@[textAttributedString, imageAttributedString]]; // 將resultAttributedString賦值給label label.attributedText = resultAttributedString; }其他圖片在文字前、在文字中的調用方式和上面的代碼類似,這里不再贅述!
PS: 關于圖文混排參考這篇文章, 寫的很好,收獲很大,感謝分享!
最后附一張屬性表圖:
image.png
轉載于:https://www.cnblogs.com/shenlaiyaoshi/p/8555342.html
總結
- 上一篇: c# vs2010 excel 上传or
- 下一篇: VM虚拟机链接克隆及linux eth0