生活随笔
收集整理的這篇文章主要介紹了
ios NSAttributedString 具体解释
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
ios NSAttributedString 具體解釋
NSAttributedString能夠讓我們使一個字符串顯示的多樣化,可是眼下到iOS 5為止,好像對它支持的不是非常好,由于顯示起來不太方便(至少沒有在OS X上方便)。
首先導入CoreText.framework,并在須要使用的文件里導入:
#import <CoreText/CoreText.h>
創建一個NSMutableAttributedString:
NSMutableAttributedString?*attriString?=?[[[NSMutableAttributedString?alloc]?initWithString:@"this?is?test!" ]??? ??????????????????????????????????????????????autorelease];?? 很常規的創建方式,接下來我們給它配置屬性:
?? [attriString?addAttribute:(NSString?*)kCTForegroundColorAttributeName?? ????????????????????value:(id)[UIColor?redColor].CGColor??? ????????????????????range:NSMakeRange(0,?4)];?? ?? [attriString?addAttribute:(NSString?*)kCTForegroundColorAttributeName?? ????????????????????value:(id)[UIColor?yellowColor].CGColor??? ????????????????????range:NSMakeRange(5,?2)];?? ?? [attriString?addAttribute:(NSString?*)kCTFontAttributeName?? ????????????????????value:(id)CTFontCreateWithName((CFStringRef)[UIFont?boldSystemFontOfSize:14].fontName,?? ???????????????????????????????????????????????????14,??? ???????????????????????????????????????????????????NULL)?? ????????????????????range:NSMakeRange(0,?4)];?? ?? [attriString?addAttribute:(NSString?*)kCTUnderlineStyleAttributeName?
????????????????????value:(id)[NSNumber?numberWithInt:kCTUnderlineStyleDouble]?? ????????????????????range:NSMakeRange(0,?4)];?? return ?attriString;?? 這樣就算是配置好了,可是我們能夠發現NSAttributedString繼承于NSObject,而且不支持不論什么draw的方法,那我們就僅僅能自己draw了。寫一個UIView的子類(如果命名為TView),在initWithFrame中把背景色設為透明(self.backgroundColor = [UIColor clearColor]),然后在重寫drawRect方法:
-(void )drawRect:(CGRect)rect{?? ????[super?drawRect:rect];?? ?????? ????NSAttributedString?*attriString?=?getAttributedString();?? ?????? ????CGContextRef?ctx?=?UIGraphicsGetCurrentContext();?? ????CGContextConcatCTM(ctx,?CGAffineTransformScale(CGAffineTransformMakeTranslation(0,?rect.size.height),?1.f,?-1.f));?? ?????? ????CTFramesetterRef?framesetter?=?CTFramesetterCreateWithAttributedString((CFAttributedStringRef)attriString);?? ????CGMutablePathRef?path?=?CGPathCreateMutable();?? ????CGPathAddRect(path,?NULL,?rect);?? ?????? ????CTFrameRef?frame?=?CTFramesetterCreateFrame(framesetter,?CFRangeMake(0,?0),?path,?NULL);?? ????CFRelease(path);?? ????CFRelease(framesetter);?? ?????? ????CTFrameDraw(frame,?ctx);?? ????CFRelease(frame);?? }?? 在代碼中我們調整了CTM(current transformation matrix),這是由于Quartz 2D的坐標系統不同,比方(10, 10)到(20, 20)的直線坐標:
?
坐標類似于數學中的坐標,能夠先不調整CTM,看它是什么樣子的,以下兩種調整方法是全然一樣的:
CGContextConcatCTM(ctx,?CGAffineTransformScale(CGAffineTransformMakeTranslation(0,?rect.size.height),?1.f,?-1.f));?? ==
CGContextTranslateCTM(ctx,?0,?rect.size.height);?? CGContextScaleCTM(ctx,?1,?-1);?? CTFramesetter是CTFrame的創建工廠,NSAttributedString須要通過CTFrame繪制到界面上,得到CTFramesetter后,創建path(繪制路徑),然后得到CTFrame,最后通過CTFrameDraw方法繪制到界面上 。
假設想要計算NSAttributedString所要的size,就須要用到這個API:
CTFramesetterSuggestFrameSizeWithConstraints,用NSString的sizeWithFont算多行時會算不準的,由于在CoreText里,行間距也是你來控制的。
設置行間距和換行模式都是設置一個屬性:kCTParagraphStyleAttributeName,這個屬性里面又分為非常多子
屬性,當中就包含
kCTLineBreakByCharWrapping kCTParagraphStyleSpecifierLineSpacingAdjustment 設置例如以下:
?? ?????? CTParagraphStyleSetting?lineBreakMode;?? CTLineBreakMode?lineBreak?=?kCTLineBreakByCharWrapping;??? lineBreakMode.spec?=?kCTParagraphStyleSpecifierLineBreakMode;?? lineBreakMode.value?=?&lineBreak;?? lineBreakMode.valueSize?=?sizeof (CTLineBreakMode);?? ?????? CTParagraphStyleSetting?LineSpacing;?? CGFloat?spacing?=?4.0;???? LineSpacing.spec?=?kCTParagraphStyleSpecifierLineSpacingAdjustment;?? LineSpacing.value?=?&spacing;?? LineSpacing.valueSize?=?sizeof (CGFloat);?? ?? CTParagraphStyleSetting?settings[]?=?{lineBreakMode,LineSpacing};?? CTParagraphStyleRef?paragraphStyle?=?CTParagraphStyleCreate(settings,?2);????? [attributedString?addAttribute:(NSString?*)kCTParagraphStyleAttributeName?? ?????????????????????????value:(id)paragraphStyle?? ?????????????????????????range:NSMakeRange(0,?attributedString.length)];?? -----------------------------------------猥瑣的分界線-----------------------------------------
這并非唯一的方法,還有還有一種替代方案:
CATextLayer?*textLayer?=?[CATextLayer?layer];?? textLayer.string?=?getAttributedString();?? textLayer.frame?=?CGRectMake(0,?CGRectGetMaxY(view.frame),?200,?200);?? [self.view.layer?addSublayer:textLayer];?? CATextLayer能夠直接支持NSAttributedString!
-----------------------------------------猥瑣的分界線-----------------------------------------
效果圖:
源代碼地址 -----------------------------------------猥瑣的分界線----------------------------------------- 眼下發現有一個問題,好像中文全都會被加粗,設置不加粗的字體也沒用,應該是CoreText的bug,已經上報給了apple了。
----------------------------------------- 對于cythb兄提出的問題 ----------------------------------------- 首先表示感謝關注 原文中確有描寫敘述不適當的地方,比方:The upper-left corner of the context is (0, 0) 。實際上Quartz2D的坐標系統確實在左下角,僅僅是有一些技術在設置它們的graphics context時使用了不同于Quartz的默認坐標系統。相對于Quartz來說,這些坐標系統是改動的坐標系統(modified coordinate system)。
UPDATED 在iOS6之后,創建一個AttributedString變成了一件輕松的事情,
<CoreText/CoreText.h> 已經不須要導入了。假設我要設置字體的顏色,能夠直接這樣:
[textAttr?addAttribute :NSForegroundColorAttributeName?? ???????????????????????value :[UIColor?redColor ]?? ???????????????????????range :NSMakeRange(0 ,?text.length )];?
總結
以上是生活随笔 為你收集整理的ios NSAttributedString 具体解释 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。