iOS - 富文本AttributedString

最近項目中用到了圖文混排,所以就研究了一下iOS中的富文本,打算把研究的結果分享一下,也是對自己學習的一個總結。

在iOS中或者Mac OS X中怎樣才能將一個字符串繪制到屏幕上呢?

簡單來說,是通過控件來完成的,而這些控件都封裝在UIKit框架中(對于Mac OS X是AppKit框架),在UIKit中常用來在屏幕上顯示字符串的控件有3個:
   UILabelUITextFieldUITextView

?

然而這些控件本身對文本的展現方式很單一,通常僅僅能夠控制字體樣式、大小、顏色、加粗、斜體等等,而對于行距控制,字距控制,段落控制等高級功能卻無能為力。
此時不免要提起一個非常強大的文本排版框架CoreText.framework。
CoreText框架是基于 iOS 3.2+ 和 OSX 10.5+ 的一種能夠對文本格式和文本布局進行精細控制的文本引擎。它良好的結合了 UIKit 和 Core Graphics/Quartz:
  UIKit 的 UILabel 允許你通過在 IB 中簡單的拖曳添加文本,但你不能改變文本的顏色和其中的單詞。Core Graphics/Quartz幾乎允許你做任何系統允許的事情,但你需要為每個字形計算位置,并畫在屏幕上。

?

CoreText正結合了這兩者!你自己可以完全控制位置、布局、類似文本大小和顏色這樣的屬性,CoreText將幫你完善其它的東西——類似文本換行、字體呈現等等。
然而,CoreText.framework本身非常龐大,學習成本較高,使用起來也不是很方便,所以一般不是特殊需要,很少會有人去使用它。
隨著iOS6 API的發布,文字顯示的API越來越完善,其中一個重要的更新是在UITextField,UITextView和UILabel中加入了對AttributedString的支持,實現行距控制,字距控制,段落控制等高級功能也不必再去使用深奧的CoreText框架。
而iOS7的發布,蘋果又引入了TextKit,TextKit是一個快速而又現代化的文字排版和渲染引擎。
TextKit并沒有新增類,只是在原有的文本顯示控件上進行了封裝,可以在平時我們最喜歡使用的UILabel,UITextField,UITextView等控件里面使用,其最主要的作用就是為程序提供文字排版和渲染的功能。
蘋果引入TextKit的目的并非要取代已有的CoreText框架,雖然CoreText的主要作用也是用于文字的排版和渲染,但它是一種先進而又處于底層技術,如果我們需要將文本內容直接渲染到圖形上下文(Graphics context)時,從性能和易用性來考慮,最佳方案就是使用CoreText。而如果我們需要直接利用蘋果提供的一些控件(如UITextView、UILabel和UITextField等)對文字進行排版,那么借助于UIKit中TextKit提供的API無疑更為方便快捷。
TextKit在文字處理方面具有非常強大的功能,并且開發者可以對TextKit進行定制和擴展。據悉,蘋果利用了2年的時間來開發TextKit,相信這對許多開發者來說都是福音。
然而,無論CoreText還是TextKit都不在本文討論的范疇,因為它們都是非常龐大的體系,而我們的需求通過一個簡單小巧的AttributedString就可以輕松搞定,所以本文的關注點只有一個,那就是AttributedString,至于CoreText和TextKit,在真正需要的時候再進行深入研究和總結。
OK,啰嗦完畢,進入正題。
與NSString類似,在iOS中AttributedString也分為NSAttributedString和NSMutableAttributedString,不同的是,AttributedString對象多了一個Attribute的概念,一個AttributedString的對象包含很多的屬性,每一個屬性都有其對應的字符區域,在這里是使用NSRange來進行描述的。
使用AttributedString的方式通常有兩種:
方式一:
首先初始化一個NSMutableAttributedString,然后向里面添加文字樣式,最后將它賦給控件的AttributedText,該方法適合于文本較少而又需要分段精細控制的情況。
NSString *originStr = @"Hello,中秋節!";//方式一//創建 NSMutableAttributedString
NSMutableAttributedString *attributedStr01 = [[NSMutableAttributedString alloc] initWithString: originStr];//添加屬性//給所有字符設置字體為Zapfino,字體高度為15像素
[attributedStr01 addAttribute: NSFontAttributeName value: [UIFont fontWithName: @"Zapfino" size: 15]range: NSMakeRange(0, originStr.length)];
//分段控制,最開始4個字符顏色設置成藍色
[attributedStr01 addAttribute: NSForegroundColorAttributeName value: [UIColor blueColor] range: NSMakeRange(0, 4)];
//分段控制,第5個字符開始的3個字符,即第5、6、7字符設置為紅色
[attributedStr01 addAttribute: NSForegroundColorAttributeName value: [UIColor redColor] range: NSMakeRange(4, 3)];//賦值給顯示控件label01的 attributedText
_label01.attributedText = attributedStr01;

?

方式二:
首先創建屬性字典,初始化各種屬性,然后和需要控制的文本一起創建并賦值給控件的AttributedText,該方法適合于需要控制的文本較多整體控制的情況,通常是從文件中讀取的大段文本控制。
//方式二//創建屬性字典
NSDictionary *attrDict = @{ NSFontAttributeName: [UIFont fontWithName: @"Zapfino" size: 15],NSForegroundColorAttributeName: [UIColor blueColor] };//創建 NSAttributedString 并賦值
_label02.attributedText = [[NSAttributedString alloc] initWithString: originStr attributes: attrDict];通過對比兩個例子可以看出,方式一比較容易處理復雜的格式,但是屬性設置比較繁多復雜,而方式二的屬性設置比較簡單明了,卻不善于處理復雜多樣的格式控制,但是不善于并不等于不能,可以通過屬性字符串分段的方式來達到方式一的效果,如下://方式二的分段處理
//第一段
NSDictionary *attrDict1 = @{ NSFontAttributeName: [UIFont fontWithName: @"Zapfino" size: 15],NSForegroundColorAttributeName: [UIColor blueColor] };
NSAttributedString *attrStr1 = [[NSAttributedString alloc] initWithString: [originStr substringWithRange: NSMakeRange(0, 4)] attributes: attrDict1];//第二段
NSDictionary *attrDict2 = @{ NSFontAttributeName: [UIFont fontWithName: @"Zapfino" size: 15],NSForegroundColorAttributeName: [UIColor redColor] };
NSAttributedString *attrStr2 = [[NSAttributedString alloc] initWithString: [originStr substringWithRange: NSMakeRange(4, 3)] attributes: attrDict2];//第三段
NSDictionary *attrDict3 = @{ NSFontAttributeName: [UIFont fontWithName: @"Zapfino" size: 15],NSForegroundColorAttributeName: [UIColor blackColor] };
NSAttributedString *attrStr3 = [[NSAttributedString alloc] initWithString: [originStr substringWithRange:NSMakeRange(7, originStr.length - 4 - 3)] attributes: attrDict3];
//合并
NSMutableAttributedString *attributedStr03 = [[NSMutableAttributedString alloc] initWithAttributedString: attrStr1];
[attributedStr03 appendAttributedString: attrStr2];
[attributedStr03 appendAttributedString: attrStr3];_label03.attributedText = attributedStr03;

?

好了,講完AttributedString的創建方式,下面研究下AttributedString究竟可以設置哪些屬性,具體來說,有以下21個:
// NSFontAttributeName                設置字體屬性,默認值:字體:Helvetica(Neue) 字號:12
// NSForegroundColorAttributeNam      設置字體顏色,取值為 UIColor對象,默認值為黑色
// NSBackgroundColorAttributeName     設置字體所在區域背景顏色,取值為 UIColor對象,默認值為nil, 透明色
// NSLigatureAttributeName            設置連體屬性,取值為NSNumber 對象(整數),0 表示沒有連體字符,1 表示使用默認的連體字符
// NSKernAttributeName                設定字符間距,取值為 NSNumber 對象(整數),正值間距加寬,負值間距變窄
// NSStrikethroughStyleAttributeName  設置刪除線,取值為 NSNumber 對象(整數)
// NSStrikethroughColorAttributeName  設置刪除線顏色,取值為 UIColor 對象,默認值為黑色
// NSUnderlineStyleAttributeName      設置下劃線,取值為 NSNumber 對象(整數),枚舉常量 NSUnderlineStyle中的值,與刪除線類似
// NSUnderlineColorAttributeName      設置下劃線顏色,取值為 UIColor 對象,默認值為黑色
// NSStrokeWidthAttributeName         設置筆畫寬度,取值為 NSNumber 對象(整數),負值填充效果,正值中空效果
// NSStrokeColorAttributeName         填充部分顏色,不是字體顏色,取值為 UIColor 對象
// NSShadowAttributeName              設置陰影屬性,取值為 NSShadow 對象
// NSTextEffectAttributeName          設置文本特殊效果,取值為 NSString 對象,目前只有圖版印刷效果可用:
// NSBaselineOffsetAttributeName      設置基線偏移值,取值為 NSNumber (float),正值上偏,負值下偏
// NSObliquenessAttributeName         設置字形傾斜度,取值為 NSNumber (float),正值右傾,負值左傾
// NSExpansionAttributeName           設置文本橫向拉伸屬性,取值為 NSNumber (float),正值橫向拉伸文本,負值橫向壓縮文本
// NSWritingDirectionAttributeName    設置文字書寫方向,從左向右書寫或者從右向左書寫
// NSVerticalGlyphFormAttributeName   設置文字排版方向,取值為 NSNumber 對象(整數),0 表示橫排文本,1 表示豎排文本
// NSLinkAttributeName                設置鏈接屬性,點擊后調用瀏覽器打開指定URL地址
// NSAttachmentAttributeName          設置文本附件,取值為NSTextAttachment對象,常用于文字圖片混排
// NSParagraphStyleAttributeName      設置文本段落排版格式,取值為 NSParagraphStyle 對象 

?

下面就一一舉例說明:
1. NSFontAttributeName
//NSForegroundColorAttributeName 設置字體顏色,取值為 UIColor,默認為黑色
 
NSDictionary *attrDict1 = @{ NSForegroundColorAttributeName: [UIColor redColor] };
NSDictionary *attrDict2 = @{ NSForegroundColorAttributeName: [UIColor blueColor] };
NSDictionary *attrDict3 = @{ NSForegroundColorAttributeName: [UIColor orangeColor] };_label01.attributedText = [[NSAttributedString alloc] initWithString: originStr attributes: attrDict1];
_label02.attributedText = [[NSAttributedString alloc] initWithString: originStr attributes: attrDict2];
_label03.attributedText = [[NSAttributedString alloc] initWithString: originStr attributes: attrDict3];注意:NSForegroundColorAttributeName設置的顏色與UILabel的textColor屬性設置的顏色在地位上是相等的,誰最后賦值,最終顯示的就是誰的顏色。

?

2. NSBackgroundColorAttributeName
//NSForegroundColorAttributeName 設置字體顏色,取值為 UIColor,默認為黑色
 
NSDictionary *attrDict1 = @{ NSForegroundColorAttributeName: [UIColor redColor] };
NSDictionary *attrDict2 = @{ NSForegroundColorAttributeName: [UIColor blueColor] };
NSDictionary *attrDict3 = @{ NSForegroundColorAttributeName: [UIColor orangeColor] };_label01.attributedText = [[NSAttributedString alloc] initWithString: originStr attributes: attrDict1];
_label02.attributedText = [[NSAttributedString alloc] initWithString: originStr attributes: attrDict2];
_label03.attributedText = [[NSAttributedString alloc] initWithString: originStr attributes: attrDict3];//NSBackgroundColorAttributeName 設置字體所在區域背景的顏色,取值為UIColor,默認值為nil
 
NSDictionary *attrDict4 = @{ NSBackgroundColorAttributeName: [UIColor orangeColor] };
NSDictionary *attrDict5 = @{ NSBackgroundColorAttributeName: [UIColor redColor] };
NSDictionary *attrDict6 = @{ NSBackgroundColorAttributeName: [UIColor cyanColor] };_label01.attributedText = [[NSAttributedString alloc] initWithString: originStr attributes: attrDict4];
_label02.attributedText = [[NSAttributedString alloc] initWithString: originStr attributes: attrDict5];
_label03.attributedText = [[NSAttributedString alloc] initWithString: originStr attributes: attrDict6];仔細觀察會發現個問題,我并沒有關閉 NSForegroundColorAttributeName 屬性,但是在運行結果中,所有字體的顏色都變成了默認色——黑色,這說明 NSForegroundColorAttributeName 和 NSBackgroundColorAttributeName 的低位是相等的,跟前面介紹的 textColor 一樣,哪個屬性最后一次賦值,就會沖掉前面的效果,若是我們把屬性代碼順序交換一下//NSBackgroundColorAttributeName 設置字體所在區域背景的顏色,取值為UIColor,默認值為nil
 
NSDictionary *attrDict4 = @{ NSBackgroundColorAttributeName: [UIColor orangeColor] };
NSDictionary *attrDict5 = @{ NSBackgroundColorAttributeName: [UIColor redColor] };
NSDictionary *attrDict6 = @{ NSBackgroundColorAttributeName: [UIColor cyanColor] };_label01.attributedText = [[NSAttributedString alloc] initWithString: originStr attributes: attrDict4];
_label02.attributedText = [[NSAttributedString alloc] initWithString: originStr attributes: attrDict5];
_label03.attributedText = [[NSAttributedString alloc] initWithString: originStr attributes: attrDict6];//NSForegroundColorAttributeName 設置字體顏色,取值為 UIColor,默認為黑色
 
NSDictionary *attrDict1 = @{ NSForegroundColorAttributeName: [UIColor redColor] };
NSDictionary *attrDict2 = @{ NSForegroundColorAttributeName: [UIColor blueColor] };
NSDictionary *attrDict3 = @{ NSForegroundColorAttributeName: [UIColor orangeColor] };_label01.attributedText = [[NSAttributedString alloc] initWithString: originStr attributes: attrDict1];
_label02.attributedText = [[NSAttributedString alloc] initWithString: originStr attributes: attrDict2];
_label03.attributedText = [[NSAttributedString alloc] initWithString: originStr attributes: attrDict3];但是textColor屬性可以與 NSBackgroundColorAttributeName 屬性疊加_label01.textColor = [UIColor greenColor];
_label02.textColor = [UIColor yellowColor];
_label03.textColor = [UIColor blueColor];//NSForegroundColorAttributeName 設置字體顏色,取值為 UIColor,默認為黑色
 
NSDictionary *attrDict1 = @{ NSForegroundColorAttributeName: [UIColor redColor] };
NSDictionary *attrDict2 = @{ NSForegroundColorAttributeName: [UIColor blueColor] };
NSDictionary *attrDict3 = @{ NSForegroundColorAttributeName: [UIColor orangeColor] };_label01.attributedText = [[NSAttributedString alloc] initWithString: originStr attributes: attrDict1];
_label02.attributedText = [[NSAttributedString alloc] initWithString: originStr attributes: attrDict2];
_label03.attributedText = [[NSAttributedString alloc] initWithString: originStr attributes: attrDict3];//NSBackgroundColorAttributeName 設置字體所在區域背景的顏色,取值為UIColor,默認值為nil
 
NSDictionary *attrDict4 = @{ NSBackgroundColorAttributeName: [UIColor orangeColor] };
NSDictionary *attrDict5 = @{ NSBackgroundColorAttributeName: [UIColor redColor] };
NSDictionary *attrDict6 = @{ NSBackgroundColorAttributeName: [UIColor cyanColor] };_label01.attributedText = [[NSAttributedString alloc] initWithString: originStr attributes: attrDict4];
_label02.attributedText = [[NSAttributedString alloc] initWithString: originStr attributes: attrDict5];
_label03.attributedText = [[NSAttributedString alloc] initWithString: originStr attributes: attrDict6];雖然 textColor 在 NSFontAttributeName 之前賦值,但是由于 NSFontAttributeName 的屬性效果被NSBackgroundColorAttributeName 屬性沖掉了,所以最終顯示了 textColor 的顏色。

?

3. NSLigatureAttributeName
//NSLigatureAttributeName 設置連體屬性,取值為NSNumber 對象(整數),0 表示沒有連體字符,1 表示使用默認的連體字符,
//                        2 表示使用所有連體符號,默認值為 1(iOS 不支持 2)
 
NSString *ligatureStr = @"flush";NSDictionary *attrDict1 = @{ NSLigatureAttributeName: [NSNumber numberWithInt: 0],NSFontAttributeName: [UIFont fontWithName: @"futura" size: 30] };
_label01.attributedText = [[NSAttributedString alloc] initWithString: ligatureStr attributes: attrDict1];NSDictionary *attrDict2 = @{ NSLigatureAttributeName: @(1),NSFontAttributeName: [UIFont fontWithName: @"futura" size: 30] };
_label02.attributedText = [[NSAttributedString alloc] initWithString: ligatureStr attributes: attrDict2];由于要展示連體字符,所以將前面使用的帶有中文的字符串換成 flushNSLigatureAttributeName的取值為NSNumber對象,所以不能直接將一個整數值賦給它,創建 NSNumber 對象的方法有很多,或者可以簡寫成 @(int)注意觀察字母f和l之間的變化。感覺連寫就是一個藝術字功能,當字符f和l組合使用組合符號(所謂的字形(glyph))繪制時,看起來確實更加美觀。但是并非所有的字符之間都有組合符號,事實上,只有某些字體中得某些字符的組合(如字符f和l,字符f和i等)才具有美觀的組合符號。

?

4. NSKernAttributeName
//NSKernAttributeName 設定字符間距,取值為 NSNumber 對象(整數),正值間距加寬,負值間距變窄
   NSDictionary *attrDict1 = @{ NSKernAttributeName: @(-3),NSFontAttributeName: [UIFont systemFontOfSize: 20]};_label01.attributedText = [[NSAttributedString alloc] initWithString: originStr attributes: attrDict1];NSDictionary *attrDict2 = @{ NSKernAttributeName: @(0),NSFontAttributeName: [UIFont systemFontOfSize: 20]};_label02.attributedText = [[NSAttributedString alloc] initWithString: originStr attributes: attrDict2];NSDictionary *attrDict3 = @{ NSKernAttributeName: @(10),NSFontAttributeName: [UIFont systemFontOfSize: 20]};_label03.attributedText = [[NSAttributedString alloc] initWithString: originStr attributes: attrDict3];

?

5. NSStrikethroughStyleAttributeName
//NSStrikethroughStyleAttributeName 設置刪除線,取值為 NSNumber 對象(整數),枚舉常量 NSUnderlineStyle中的值
// NSUnderlineStyleNone   不設置刪除線
// NSUnderlineStyleSingle 設置刪除線為細單實線
// NSUnderlineStyleThick  設置刪除線為粗單實線
// NSUnderlineStyleDouble 設置刪除線為細雙實線
 NSDictionary *attrDict1 = @{ NSStrikethroughStyleAttributeName: @(NSUnderlineStyleSingle),NSFontAttributeName: [UIFont systemFontOfSize:20] };
_label01.attributedText = [[NSAttributedString alloc] initWithString: originStr attributes: attrDict1];NSDictionary *attrDict2 = @{ NSStrikethroughStyleAttributeName: @(NSUnderlineStyleThick),NSFontAttributeName: [UIFont systemFontOfSize:20] };
_label02.attributedText = [[NSAttributedString alloc] initWithString: originStr attributes: attrDict2];NSDictionary *attrDict3 = @{ NSStrikethroughStyleAttributeName: @(NSUnderlineStyleDouble),NSFontAttributeName: [UIFont systemFontOfSize:20] };
_label03.attributedText = [[NSAttributedString alloc] initWithString: originStr attributes: attrDict3];
注意:雖然使用了枚舉常量,但是枚舉常量的本質仍為整數,所以同樣必須先轉化為 NSNumber 才能使用刪除線和下劃線使用相同的枚舉常量作為其屬性值目前iOS中只有上面列出的4中效果,雖然我們能夠在頭文件中發現其他更多的取值,但是使用后沒有任何效果可以看出,中文和英文刪除線的位置有所不同另外,刪除線屬性取值除了上面的4種外,其實還可以取其他整數值,有興趣的可以自行試驗,取值為 0 - 7時,效果為單實線,隨著值得增加,單實線逐漸變粗,取值為 9 - 15時,效果為雙實線,取值越大,雙實線越粗。NSDictionary *attrDict1 = @{ NSStrikethroughStyleAttributeName: @(1),NSFontAttributeName: [UIFont systemFontOfSize:20] };
_label01.attributedText = [[NSAttributedString alloc] initWithString: originStr attributes: attrDict1];NSDictionary *attrDict2 = @{ NSStrikethroughStyleAttributeName: @(3),NSFontAttributeName: [UIFont systemFontOfSize:20] };
_label02.attributedText = [[NSAttributedString alloc] initWithString: originStr attributes: attrDict2];NSDictionary *attrDict3 = @{ NSStrikethroughStyleAttributeName: @(7),NSFontAttributeName: [UIFont systemFontOfSize:20] };
_label03.attributedText = [[NSAttributedString alloc] initWithString: originStr attributes: attrDict3];

?

6. NSStrikethroughColorAttributeName
//NSStrikethroughColorAttributeName 設置刪除線顏色,取值為 UIColor 對象,默認值為黑色
   NSDictionary *attrDict1 = @{ NSStrikethroughColorAttributeName: [UIColor blueColor],NSStrikethroughStyleAttributeName: @(1),NSFontAttributeName: [UIFont systemFontOfSize:20] };_label01.attributedText = [[NSAttributedString alloc] initWithString: originStr attributes: attrDict1];NSDictionary *attrDict2 = @{ NSStrikethroughColorAttributeName: [UIColor orangeColor],NSStrikethroughStyleAttributeName: @(3),NSFontAttributeName: [UIFont systemFontOfSize:20] };_label02.attributedText = [[NSAttributedString alloc] initWithString: originStr attributes: attrDict2];NSDictionary *attrDict3 = @{ NSStrikethroughColorAttributeName: [UIColor greenColor],NSStrikethroughStyleAttributeName: @(7),NSFontAttributeName: [UIFont systemFontOfSize:20] };_label03.attributedText = [[NSAttributedString alloc] initWithString: originStr attributes: attrDict3];

?

7. NSUnderlineStyleAttributeName
  下劃線除了線條位置和刪除線不同外,其他的都可以完全參照刪除線設置。//NSUnderlineStyleAttributeName 設置下劃線,取值為 NSNumber 對象(整數),枚舉常量 NSUnderlineStyle中的值,與刪除線類似
 
NSDictionary *attrDict1 = @{ NSUnderlineStyleAttributeName: @(NSUnderlineStyleSingle),NSFontAttributeName: [UIFont systemFontOfSize:20] };
_label01.attributedText = [[NSAttributedString alloc] initWithString: originStr attributes: attrDict1];NSDictionary *attrDict2 = @{ NSUnderlineStyleAttributeName: @(NSUnderlineStyleThick),NSFontAttributeName: [UIFont systemFontOfSize:20] };
_label02.attributedText = [[NSAttributedString alloc] initWithString: originStr attributes: attrDict2];NSDictionary *attrDict3 = @{ NSUnderlineStyleAttributeName: @(NSUnderlineStyleDouble),NSFontAttributeName: [UIFont systemFontOfSize:20] };
_label03.attributedText = [[NSAttributedString alloc] initWithString: originStr attributes: attrDict3];

?

8. NSUnderlineColorAttributeName
可以完全參照下劃線顏色設置//NSUnderlineColorAttributeName 設置下劃線顏色,取值為 UIColor 對象,默認值為黑色
    NSDictionary *attrDict1 = @{ NSUnderlineColorAttributeName: [UIColor blueColor],NSUnderlineStyleAttributeName: @(NSUnderlineStyleSingle),NSFontAttributeName: [UIFont systemFontOfSize:20] };_label01.attributedText = [[NSAttributedString alloc] initWithString: originStr attributes: attrDict1];NSDictionary *attrDict2 = @{ NSUnderlineColorAttributeName: [UIColor orangeColor],NSUnderlineStyleAttributeName: @(NSUnderlineStyleThick),NSFontAttributeName: [UIFont systemFontOfSize:20] };_label02.attributedText = [[NSAttributedString alloc] initWithString: originStr attributes: attrDict2];NSDictionary *attrDict3 = @{ NSUnderlineColorAttributeName: [UIColor greenColor],NSUnderlineStyleAttributeName: @(NSUnderlineStyleDouble),NSFontAttributeName: [UIFont systemFontOfSize:20] };_label03.attributedText = [[NSAttributedString alloc] initWithString: originStr attributes: attrDict3];

?

9. NSStrokeWidthAttributeName
//NSStrokeWidthAttributeName 設置筆畫寬度,取值為 NSNumber 對象(整數),負值填充效果,正值中空效果
   NSDictionary *attrDict1 = @{ NSStrokeWidthAttributeName: @(-3),NSFontAttributeName: [UIFont systemFontOfSize:30] };_label01.attributedText = [[NSAttributedString alloc] initWithString: originStr attributes: attrDict1];NSDictionary *attrDict2 = @{ NSStrokeWidthAttributeName: @(0),NSFontAttributeName: [UIFont systemFontOfSize:30] };_label02.attributedText = [[NSAttributedString alloc] initWithString: originStr attributes: attrDict2];NSDictionary *attrDict3 = @{ NSStrokeWidthAttributeName: @(3),NSFontAttributeName: [UIFont systemFontOfSize:30] };_label03.attributedText = [[NSAttributedString alloc] initWithString: originStr attributes: attrDict3];

?

10. NSStrokeColorAttributeName
//NSStrokeColorAttributeName 填充部分顏色,不是字體顏色,取值為 UIColor 對象
    NSDictionary *attrDict1 = @{ NSStrokeWidthAttributeName: @(-3),NSStrokeColorAttributeName: [UIColor orangeColor],NSFontAttributeName: [UIFont systemFontOfSize:30] };_label01.attributedText = [[NSAttributedString alloc] initWithString: originStr attributes: attrDict1];NSDictionary *attrDict2 = @{ NSStrokeWidthAttributeName: @(0),NSStrokeColorAttributeName: [UIColor blueColor],NSFontAttributeName: [UIFont systemFontOfSize:30] };_label02.attributedText = [[NSAttributedString alloc] initWithString: originStr attributes: attrDict2];NSDictionary *attrDict3 = @{ NSStrokeWidthAttributeName: @(3),NSStrokeColorAttributeName: [UIColor greenColor],NSFontAttributeName: [UIFont systemFontOfSize:30] };_label03.attributedText = [[NSAttributedString alloc] initWithString: originStr attributes: attrDict3];

?

轉載于:https://www.cnblogs.com/gongyuhonglou/p/5576708.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/287372.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/287372.shtml
英文地址,請注明出處:http://en.pswp.cn/news/287372.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

php把數字倒著展示,jQuery+PHP實現動態數字展示特效

HTML本例假設要在頁面上動態展示(無需刷新整個頁面,只是局部刷新動態數字)當前在線用戶數,常見在一些統計平臺上應用。在HTML頁面中只需定義以下結構:代碼如下:當前在線:jQuery首先我們要定義一個動畫過程,使用jQuery的…

Android之實現多張圖片點擊預覽(支持放縮)和滑動

1 需求 多張圖片通過recycleView展示,然后點擊具體一張圖片支持預覽(支持放縮)和滑動 2 解決辦法 BaseRecyclerViewAdapterHelper com.github.chrisbanes.photoview.PhotoView ViewPage2 組合起來真香 https://github.com/CymChad/BaseRecyclerViewAdapt…

【Envi風暴】Envi5.4經典安裝圖文教程

ENVI(The Environment for Visualizing Images)是一個完整的遙感圖像處理平臺,應用匯集中的軟件處理技術覆蓋了圖像數據的輸入/輸出、圖像定標、圖像增強、糾正、正射校正、鑲嵌、數據融合以及各種變換、信息提取、圖像分類、基于知識的決策樹分類、與GIS的整合、DEM及地形信…

錯誤: nknown column 'xxxx' in 'where clause'

nknown column sdsds in where clause 運行環境:jdk1.7.0_17tomcat 7 spring:3.2.0 mybatis:3.2.7 eclipse 錯誤:nknown column sdsds in where clause 錯誤原因:數據庫查詢無用,可能很多寫sql語句都會遇到…

c/c++處理參數

直接上代碼&#xff1a;涉及函數getopt()&#xff0c;getopt_long() 1 #include <unistd.h>2 #include <stdlib.h>3 #include <stdio.h>4 #include <getopt.h>5 6 /*7 int main(int argc, char *argv[])8 {9 int opt; 10 char * optstring &q…

查缺補漏系統學習 EF Core 6 - 批量操作

推薦關注「碼俠江湖」加星標&#xff0c;時刻不忘江湖事這是 EF Core 系列的第七篇文章&#xff0c;上一篇文章講述了 EF Core 中的實體數據修改。這篇文章講一講 EF Core 如何進行批量操作。在眾多的 ORM 框架中&#xff0c;EF Core 的功能并不是最強大的那個&#xff0c;性能…

半小時一篇文過完C語言基礎知識點

若是大一學子或者是真心想學習剛入門的小伙伴可以私聊我&#xff0c;若你是真心學習可以送你書籍&#xff0c;指導你學習&#xff0c;給予你目標方向的學習路線&#xff0c;無套路&#xff0c;博客為證。 本文定位讀者為小白讀者&#xff0c;將使用最快的方法過完C語言基礎知識…

php變量的判空和類型判斷

&#xff08;1&#xff09;var_dump(); 判斷一個變量是否已經聲明并且賦值&#xff0c;并且打印類型和值 <?php $a; var_dump($a);//輸出null<?php var_dump($a);//輸出null<?php$a 10; var_dump($a);//輸出 int 10&#xff08;2&#xff09;isset() 判斷一個變量…

【Envi風暴】Envi插件大全:多波段拆分工具的巧妙使用

很多場合下需要做波段合成,比如波段432合成賦予紅綠藍,構造標準假彩色等等。合成后的文件通常包含多個單波段文件,在Envi中使用layer stacking工具將多個單波段數據合成為一個文件,如下所示: 那么問題來了,合成后的數據該怎樣拆開為原來的單波段呢?今天我們就來學習一種…

php表格怎么合并單元格格式化,table標簽的結構與合并單元格的實現方法

1.示例代碼&#xff1a;復制代碼 代碼如下:#1234一個完整的例子&#xff1a;復制代碼 代碼如下:#FirstnameLastnamePhoneQQ1qianshou111111111111111111112qianshou111111111111111111113qianshou111111111111111111114qianshou111111111111111111112.合并上下的單元格(rowspan…

Android之GridLayoutManager.setSpanSizeLookup問題

1 問題 利用BaseMultiItemQuickAdapter,用recycleView加載多布局,需要實現有些view顯示一行,有些一行顯示多個圖片。 在BaseMultiItemQuickAdapter適配器里面根據類型加載不同布局。 public ImageMultiItemAdapter(List<MultiItemEntity> data) {super(data);addIte…

《看聊天記錄都學不會C語言?太菜了吧》(9)老公餅真的有老公送?

若是大一學子或者是真心想學習剛入門的小伙伴可以私聊我&#xff0c;若你是真心學習可以送你書籍&#xff0c;指導你學習&#xff0c;給予你目標方向的學習路線&#xff0c;無套路&#xff0c;博客為證。 本系列文章將會以通俗易懂的對話方式進行教學&#xff0c;對話中將涵蓋…

@Springboot搭建項目controller層接收json格式的對象失敗

今天在使用swagger2測試的時候出錯 1、requestBody注解常用來處理content-type不是默認的application/x-www-form-urlcoded編碼的內容&#xff0c;比如說&#xff1a;application/json或者是application/xml等。一般情況下來說常用其來處理application/json類型。 2、 通過req…

『技術群里聊些啥』HttpClient 如何判斷是同一終結點

前言官方文檔對 HttpClientHandler.MaxConnectionsPerServer 屬性有如下說明&#xff1a;獲取或設置使用 HttpClient 對象發出請求時允許的最大并發連接數&#xff08;每個服務器終結點&#xff09;。請注意&#xff0c;該限制針對每個服務器終結點&#xff0c;例如&#xff0c…

【Envi風暴】Envi 5.3 SP1經典安裝手把手圖文教程(含補丁文件)

Envi 5.3具有傳感器和數據支持、圖像處理和顯示、用戶界面、二次開發等新功能,本文講解Envi 5.3 SP1完全安裝教程。 下載后的軟件包目錄如下所示: 目錄 一、Envi 5.3 SP1安裝 二、Envi 5.3 SP1下載地址 一、Envi 5.3 SP1安裝 點擊IDL_ENVI5.3 SP1win64.exe,開始安裝,…

apache php url重寫語法,apache url重寫實現偽靜態

前段時間項目為了配合seo的工作&#xff0c;把現有的php網站改成靜態頁面&#xff0c;剛拿到需求時候第一感覺就是用靜態頁面啊&#xff0c;可是看了一會以后發現頁面有點多4、50個&#xff0c;沒辦法就用比較簡單的url重寫(apache的)吧&#xff0c;去掉這個前面的#,啟用它Load…

Android之用java的socket寫服務器提示java.net.BindException: Address already in use

1 問題 在Android activity里面Java socket服務器,然后關閉activity再打開activity開啟服務的時候提示錯誤如下 java.net.BindException: Address already in use 很明顯這個,IP和端口的的socket已經使用了,我們只需要在關閉activity的時候關閉serverSocket就行了。 2 解…

《看聊天記錄都學不會C語言?太菜了吧》(10)程序媛聰明絕頂了

若是大一學子或者是真心想學習剛入門的小伙伴可以私聊我&#xff0c;若你是真心學習可以送你書籍&#xff0c;指導你學習&#xff0c;給予你目標方向的學習路線&#xff0c;無套路&#xff0c;博客為證。 本系列文章將會以通俗易懂的對話方式進行教學&#xff0c;對話中將涵蓋…

List 集合轉換為String

開發中會用到把 List<string> 的內容拼接成以逗號分隔的字符串的形式,現總結如下&#xff1a; 方法一: public String listToString(List list, char separator) { StringBuilder sb new StringBuilder(); for (int i 0; i < list.size(); i) { …

[leetcode]Pascal#39;s Triangle II

問題敘述性說明&#xff1a; Given an index k, return the kth row of the Pascals triangle. For example, given k 3, Return [1,3,3,1]. Note: Could you optimize your algorithm to use only O(k) extra space? 思路&#xff1a; the mth element of the nth row of th…