/*將符號轉換為上標*/
-(NSMutableAttributedString *)changeToSuperscriptForNumberSignWith:(NSString *)string changeString:(NSString *)changeString{
NSRange range = [string rangeOfString:changeString];
NSMutableAttributedString * attributedString = [[NSMutableAttributedString alloc]initWithString:string];
NSDictionary * attris = @{NSBaselineOffsetAttributeName:@(3),
NSFontAttributeName:[UIFont systemFontOfSize:9]};
[attributedString setAttributes:attris range:range];
return attributedString;
}
NSAttributedString可以讓我們使一個字符串顯示的多樣化胖笛,但是目前到iOS 5為止梢夯,好像對它支持的不是很好驯鳖,因為顯示起來不太方便(至少沒有在OS X上方便)。
首先導入CoreText.framework,并在需要使用的文件中導入:
#import
創(chuàng)建一個NSMutableAttributedString:
1NSMutableAttributedString*attriString?=?[[[NSMutableAttributedStringalloc]initWithString:@"this?is?test!"]
2autorelease];
非常常規(guī)的創(chuàng)建方式,接下來我們給它配置屬性:
1//把this的字體顏色變?yōu)榧t色
2[attriStringaddAttribute:(NSString*)kCTForegroundColorAttributeName
3value:(id)[UIColorredColor].CGColor
4range:NSMakeRange(0,?4)];
5//把is變?yōu)辄S色
6[attriStringaddAttribute:(NSString*)kCTForegroundColorAttributeName
7value:(id)[UIColoryellowColor].CGColor
8range:NSMakeRange(5,?2)];
9//改變this的字體,value必須是一個CTFontRef
10[attriStringaddAttribute:(NSString*)kCTFontAttributeName
11value:(id)CTFontCreateWithName((CFStringRef)[UIFontboldSystemFontOfSize:14].fontName,
1214,
13NULL)
14range:NSMakeRange(0,?4)];
15//給this加上下劃線冗荸,value可以在指定的枚舉中選擇
16[attriStringaddAttribute:(NSString*)kCTUnderlineStyleAttributeName
17value:(id)[NSNumbernumberWithInt:kCTUnderlineStyleDouble]
18range:NSMakeRange(0,?4)];
19returnattriString;
這樣就算是配置好了,但是我們可以發(fā)現NSAttributedString繼承于NSObject利耍,并且不支持任何draw的方法蚌本,那我們就只能自己draw了。寫一個UIView的子類(假設命名為TView)隘梨,在initWithFrame中把背景色設為透明(self.backgroundColor = [UIColor clearColor])程癌,然后在重寫drawRect方法:
1-(void)drawRect:(CGRect)rect{
2[superdrawRect:rect];
3
4NSAttributedString*attriString?=?getAttributedString();
5
6CGContextRef?ctx?=?UIGraphicsGetCurrentContext();
7CGContextConcatCTM(ctx,?CGAffineTransformScale(CGAffineTransformMakeTranslation(0,?rect.size.height),?1.f,?-1.f));
8
9CTFramesetterRef?framesetter?=?CTFramesetterCreateWithAttributedString((CFAttributedStringRef)attriString);
10CGMutablePathRef?path?=?CGPathCreateMutable();
11CGPathAddRect(path,NULL,?rect);
12
13CTFrameRef?frame?=?CTFramesetterCreateFrame(framesetter,?CFRangeMake(0,?0),?path,NULL);
14CFRelease(path);
15CFRelease(framesetter);
16
17CTFrameDraw(frame,?ctx);
18CFRelease(frame);
19}
在代碼中我們調整了CTM(current transformation matrix),這是因為Quartz 2D的坐標系統(tǒng)不同轴猎,比如(10, 10)到(20, 20)的直線坐標:
坐標類似于數學中的坐標嵌莉,可以先不調整CTM,看它是什么樣子的捻脖,下面兩種調整方法是完全一樣的:
1CGContextConcatCTM(ctx,?CGAffineTransformScale(CGAffineTransformMakeTranslation(0,?rect.size.height),?1.f,?-1.f));
==
1CGContextTranslateCTM(ctx,?0,?rect.size.height);
2CGContextScaleCTM(ctx,?1,?-1);
CTFramesetter是CTFrame的創(chuàng)建工廠锐峭,NSAttributedString需要通過CTFrame繪制到界面上,得到CTFramesetter后可婶,創(chuàng)建path(繪制路徑)沿癞,然后得到CTFrame,最后通過CTFrameDraw方法繪制到界面上矛渴。
如果想要計算NSAttributedString所要的size椎扬,就需要用到這個API:
CTFramesetterSuggestFrameSizeWithConstraints,用NSString的sizeWithFont算多行時會算不準的具温,因為在CoreText里蚕涤,行間距也是你來控制的。
設置行間距和換行模式都是設置一個屬性:kCTParagraphStyleAttributeName铣猩,這個屬性里面又分為很多子
屬性揖铜,其中就包括
? kCTLineBreakByCharWrapping
? kCTParagraphStyleSpecifierLineSpacingAdjustment
設置如下:
1//段落
2//line?break
3CTParagraphStyleSetting?lineBreakMode;
4CTLineBreakMode?lineBreak?=?kCTLineBreakByCharWrapping;//換行模式
5lineBreakMode.spec?=?kCTParagraphStyleSpecifierLineBreakMode;
6lineBreakMode.value?=?&lineBreak;
7lineBreakMode.valueSize?=sizeof(CTLineBreakMode);
8//行間距
9CTParagraphStyleSetting?LineSpacing;
10CGFloat?spacing?=?4.0;//指定間距
11LineSpacing.spec?=?kCTParagraphStyleSpecifierLineSpacingAdjustment;
12LineSpacing.value?=?&spacing;
13LineSpacing.valueSize?=sizeof(CGFloat);
14
15CTParagraphStyleSetting?settings[]?=?{lineBreakMode,LineSpacing};
16CTParagraphStyleRef?paragraphStyle?=?CTParagraphStyleCreate(settings,?2);//第二個參數為settings的長度
17[attributedStringaddAttribute:(NSString*)kCTParagraphStyleAttributeName
18value:(id)paragraphStyle
19range:NSMakeRange(0,?attributedString.length)];
-----------------------------------------猥瑣的分界線-----------------------------------------
這并不是唯一的方法,還有另一種替代方案:
1CATextLayer*textLayer?=?[CATextLayerlayer];
2textLayer.string?=?getAttributedString();
3textLayer.frame?=?CGRectMake(0,?CGRectGetMaxY(view.frame),?200,?200);
4[self.view.layeraddSublayer:textLayer];
CATextLayer可以直接支持NSAttributedString剂习!
-----------------------------------------猥瑣的分界線-----------------------------------------
效果圖:
文本屬性Attributes
1.NSKernAttributeName: @10 調整字句 kerning 字句調整
2.NSFontAttributeName : [UIFont systemFontOfSize:_fontSize] 設置字體
3.NSForegroundColorAttributeName :[UIColor redColor] 設置文字顏色
4.NSParagraphStyleAttributeName : paragraph 設置段落樣式
5.NSMutableParagraphStyle *paragraph = [[NSMutableParagraphStyle alloc] init];
paragraph.alignment = NSTextAlignmentCenter;
6.NSBackgroundColorAttributeName: [UIColor blackColor] 設置背景顏色
7.NSStrokeColorAttributeName設置文字描邊顏色,需要和NSStrokeWidthAttributeName設置描邊寬度较沪,這樣就能使文字空心.
NSStrokeWidthAttributeName這個屬性所對應的值是一個 NSNumber 對象(小數)鳞绕。該值改變描邊寬度(相對于字體size 的百分比)。默認為 0尸曼,即不改變们何。正數只改變描邊寬度。負數同時改變文字的描邊和填充寬度控轿。例如冤竹,對于常見的空心字拂封,這個值通常為3.0。
同時設置了空心的兩個屬性鹦蠕,并且NSStrokeWidthAttributeName屬性設置為整數冒签,文字前景色就無效果了
效果:
效果:
8. NSStrikethroughStyleAttributeName 添加刪除線,strikethrough刪除線
效果:
9. NSUnderlineStyleAttributeName 添加下劃線
效果:
10. NSShadowAttributeName 設置陰影钟病,單獨設置不好使萧恕,必須和其他屬性搭配才好使。
和這三個任一個都好使肠阱,NSVerticalGlyphFormAttributeName票唆,NSObliquenessAttributeName,NSExpansionAttributeName
11.NSVerticalGlyphFormAttributeName
該屬性所對應的值是一個 NSNumber 對象(整數)屹徘。0 表示橫排文本走趋。1 表示豎排文本。在 iOS 中噪伊,總是使用橫排文本簿煌,0 以外的值都未定義。
效果:
12. NSObliquenessAttributeName設置字體傾斜酥宴。Skew 斜
效果:
13. NSExpansionAttributeName 設置文本扁平化