NSAttributedString的设置

/*将符号转换为上标*/

-(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

创建一个NSMutableAttributedString:

1NSMutableAttributedString*attriString = [[[NSMutableAttributedStringalloc]initWithString:@"this is test!"]

2autorelease];

非常常规的创建方式,接下来我们给它配置属性:

1//把this的字体颜色变为红色

2[attriStringaddAttribute:(NSString*)kCTForegroundColorAttributeName

3value:(id)[UIColorredColor].CGColor

4range:NSMakeRange(0, 4)];

5//把is变为黄色

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;

这样就算是配置好了,但是我们可以发现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的坐标系统不同,比如(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的创建工厂,NSAttributedString需要通过CTFrame绘制到界面上,得到CTFramesetter后,创建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 设置文本扁平化

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容