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];
很常规的创建方式,接下来我们给它配置属性:
- //把this的字体颜色变为红色
- [attriString addAttribute:(NSString *)kCTForegroundColorAttributeName
- value:(id)[UIColor redColor].CGColor
- range:NSMakeRange(0, 4)];
- //把is变为黄色
- [attriString addAttribute:(NSString *)kCTForegroundColorAttributeName
- value:(id)[UIColor yellowColor].CGColor
- range:NSMakeRange(5, 2)];
- //改变this的字体,value必须是一个CTFontRef
- [attriString addAttribute:(NSString *)kCTFontAttributeName
- value:(id)CTFontCreateWithName((CFStringRef)[UIFont boldSystemFontOfSize:14].fontName,
- 14,
- NULL)
- range:NSMakeRange(0, 4)];
- //给this加上下划线,value能够在指定的枚举中选择
- [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
- //段落
- //line break
- 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); //第二个參数为settings的长度
- [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!
-----------------------------------------猥琐的分界线-----------------------------------------
效果图:

源代码地址

原文中确有描写叙述不适当的地方,比方: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 具体解释的更多相关文章
- iOS SDK具体解释之NSCopying协议
原创blog,转载请注明出处 http://blog.csdn.net/hello_hwc?viewmode=contents 欢迎关注我的iOS SDK具体解释专栏 http://blog.csdn ...
- iOS SDK具体解释之UIDevice(系统版本号,设备型号...)
原创Blog,转载请注明出处 blog.csdn.net/hello_hwc 欢迎关注我的iOS SDK具体解释专栏 blog.csdn.net/column/details/huangwenchen ...
- iOS Animation具体解释
iOS Animation具体解释 本篇仅仅要解说iOS中动画的使用. Animtion主要分为两类:UIView动画和CoreAnimation动画. UIView动画有UIView属性动画,UIV ...
- iOS --NSAttributedString
字符属性可以应用于 attributed string 的文本中. 文/iOS_成才录(简书作者) 原文链接:http://www.jianshu.com/p/03a741246737 著作权归作者所 ...
- iOS 严重问题解释(crash)
问题1:Exception Type: 00000020 Exception Codes: 0x000000008badf00d Exception Note: SIMULATED (this is ...
- iOS常识名词解释 2016/04/05
Bundle : http://www.cnblogs.com/BigPolarBear/archive/2012/03/28/2421802.html http://blog.sina.com.cn ...
- 【精】iOS GCD 具体解释
一.介绍 1.什么是GCD? Grand Central Dispatch.是苹果公司开发的一套多核编程的底层API. GCD首次公布在Mac OS X 10.6,iOS4及以上也可用.GCD存在于l ...
- 关于IOS框架的解释
- iOS Core Animation具体解释(四)AutoLayout中的动画
原创blog.转载请注明出处 blog.csdn.net/hello_hwc 欢迎关注我的iOS SDK具体解释专栏 http://blog.csdn.net/column/details/huang ...
随机推荐
- LeetCode(116) Populating Next Right Pointers in Each Node
题目 Given a binary tree struct TreeLinkNode { TreeLinkNode *left; TreeLinkNode *right; TreeLinkNode * ...
- tomcat启动后 404 页面无法访问
如果修改端口后还不能访问,先关闭tomcat, 在bin目录下命令 ./shutdown.sh 找到80进程 netstat -an | grep 80 杀死80进程 ps -ef | grep h ...
- IOS 自动布局-UIStackPanel和UIGridPanel(五)
试想这样的一个需求场合,一个button靠右显示,并且距离superView的顶部和右边间距分别为10和5.如下图所示: 要实现这样的需求,如果不用自动布局技术,那么我们能想到的就是老老实实的使用绝对 ...
- 算法复习——2—sat(bzoj2199)
题目: Description 由于对Farmer John的领导感到极其不悦,奶牛们退出了农场,组建了奶牛议会.议会以“每头牛 都可以获得自己想要的”为原则,建立了下面的投票系统: M只到场的奶牛 ...
- 算法复习——平面分治(hud1007)
题目: 问题描述 : Have you ever played quoit in a playground? Quoit is a game in which flat rings are pitch ...
- P2085 最小函数值 (堆)
题目描述 有n个函数,分别为F1,F2,...,Fn.定义Fi(x)=Aix^2+Bix+Ci (x∈N*).给定这些Ai.Bi和Ci,请求出所有函数的所有函数值中最小的m个(如有重复的要输出多个). ...
- LinkedList的构造函数有哪些
LinkedList构造函数有(两种): public LinkedList() public LinkedList(Collection<? extends E> c) /** * Co ...
- Java中的自动类型转换
Java里所有的数值型变量可以进行类型转换,这个大家都知道,应该不需要详细解释为什么. 2 在说明自动类型转换之前必须理解这样一个原则“表数范围小的可以向表数范围大的进行自动类型转换” 3 关于jav ...
- POJ2560 Freckles
Time Limit: 1000MS Memory Limit: 65536KB 64bit IO Format: %lld & %llu Description In an epis ...
- 转 DOS 8.3 文件名命名规则
http://www.360doc.com/content/10/0813/14/73007_45757514.shtml DOS 8.3 文件名命名规则 经常看到命令行或者其它软件在显示目录的时候出 ...