ios NSAttributedString 具体解释

NSAttributedString能够让我们使一个字符串显示的多样化,可是眼下到iOS 5为止,好像对它支持的不是非常好,由于显示起来不太方便(至少没有在OS X上方便)。

首先导入CoreText.framework,并在须要使用的文件里导入:

#import<CoreText/CoreText.h>

创建一个NSMutableAttributedString:

  1. NSMutableAttributedString *attriString = [[[NSMutableAttributedString alloc] initWithString:@"this is test!"]
  2. autorelease];

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

  1. //把this的字体颜色变为红色
  2. [attriString addAttribute:(NSString *)kCTForegroundColorAttributeName
  3. value:(id)[UIColor redColor].CGColor
  4. range:NSMakeRange(0, 4)];
  5. //把is变为黄色
  6. [attriString addAttribute:(NSString *)kCTForegroundColorAttributeName
  7. value:(id)[UIColor yellowColor].CGColor
  8. range:NSMakeRange(5, 2)];
  9. //改变this的字体,value必须是一个CTFontRef
  10. [attriString addAttribute:(NSString *)kCTFontAttributeName
  11. value:(id)CTFontCreateWithName((CFStringRef)[UIFont boldSystemFontOfSize:14].fontName,
  12. 14,
  13. NULL)
  14. range:NSMakeRange(0, 4)];
  15. //给this加上下划线,value能够在指定的枚举中选择
  16. [attriString addAttribute:(NSString *)kCTUnderlineStyleAttributeName
  1. value:(id)[NSNumber numberWithInt:kCTUnderlineStyleDouble]
  2. range:NSMakeRange(0, 4)];
  3. return attriString;

这样就算是配置好了,可是我们能够发现NSAttributedString继承于NSObject,而且不支持不论什么draw的方法,那我们就仅仅能自己draw了。写一个UIView的子类(如果命名为TView),在initWithFrame中把背景色设为透明(self.backgroundColor = [UIColor clearColor]),然后在重写drawRect方法:

  1. -(void)drawRect:(CGRect)rect{
  2. [super drawRect:rect];
  3. NSAttributedString *attriString = getAttributedString();
  4. CGContextRef ctx = UIGraphicsGetCurrentContext();
  5. CGContextConcatCTM(ctx, CGAffineTransformScale(CGAffineTransformMakeTranslation(0, rect.size.height), 1.f, -1.f));
  6. CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)attriString);
  7. CGMutablePathRef path = CGPathCreateMutable();
  8. CGPathAddRect(path, NULL, rect);
  9. CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, NULL);
  10. CFRelease(path);
  11. CFRelease(framesetter);
  12. CTFrameDraw(frame, ctx);
  13. CFRelease(frame);
  14. }

在代码中我们调整了CTM(current transformation matrix),这是由于Quartz 2D的坐标系统不同,比方(10, 10)到(20, 20)的直线坐标:

坐标类似于数学中的坐标,能够先不调整CTM,看它是什么样子的,以下两种调整方法是全然一样的:

  1. CGContextConcatCTM(ctx, CGAffineTransformScale(CGAffineTransformMakeTranslation(0, rect.size.height), 1.f, -1.f));

==

  1. CGContextTranslateCTM(ctx, 0, rect.size.height);
  2. CGContextScaleCTM(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
  3. CTParagraphStyleSetting lineBreakMode;
  4. CTLineBreakMode lineBreak = kCTLineBreakByCharWrapping; //换行模式
  5. lineBreakMode.spec = kCTParagraphStyleSpecifierLineBreakMode;
  6. lineBreakMode.value = &lineBreak;
  7. lineBreakMode.valueSize = sizeof(CTLineBreakMode);
  8. //行间距
  9. CTParagraphStyleSetting LineSpacing;
  10. CGFloat spacing = 4.0;  //指定间距
  11. LineSpacing.spec = kCTParagraphStyleSpecifierLineSpacingAdjustment;
  12. LineSpacing.value = &spacing;
  13. LineSpacing.valueSize = sizeof(CGFloat);
  14. CTParagraphStyleSetting settings[] = {lineBreakMode,LineSpacing};
  15. CTParagraphStyleRef paragraphStyle = CTParagraphStyleCreate(settings, 2);   //第二个參数为settings的长度
  16. [attributedString addAttribute:(NSString *)kCTParagraphStyleAttributeName
  17. value:(id)paragraphStyle
  18. range:NSMakeRange(0, attributedString.length)];

-----------------------------------------猥琐的分界线-----------------------------------------

这并非唯一的方法,还有还有一种替代方案:

  1. CATextLayer *textLayer = [CATextLayer layer];
  2. textLayer.string = getAttributedString();
  3. textLayer.frame = CGRectMake(0, CGRectGetMaxY(view.frame), 200, 200);
  4. [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>已经不须要导入了。假设我要设置字体的颜色,能够直接这样:

  1. [textAttr addAttribute:NSForegroundColorAttributeName
  2. value:[UIColor redColor]
  3. range:NSMakeRange(0, text.length)];

ios NSAttributedString 具体解释的更多相关文章

  1. iOS SDK具体解释之NSCopying协议

    原创blog,转载请注明出处 http://blog.csdn.net/hello_hwc?viewmode=contents 欢迎关注我的iOS SDK具体解释专栏 http://blog.csdn ...

  2. iOS SDK具体解释之UIDevice(系统版本号,设备型号...)

    原创Blog,转载请注明出处 blog.csdn.net/hello_hwc 欢迎关注我的iOS SDK具体解释专栏 blog.csdn.net/column/details/huangwenchen ...

  3. iOS Animation具体解释

    iOS Animation具体解释 本篇仅仅要解说iOS中动画的使用. Animtion主要分为两类:UIView动画和CoreAnimation动画. UIView动画有UIView属性动画,UIV ...

  4. iOS --NSAttributedString

    字符属性可以应用于 attributed string 的文本中. 文/iOS_成才录(简书作者) 原文链接:http://www.jianshu.com/p/03a741246737 著作权归作者所 ...

  5. iOS 严重问题解释(crash)

    问题1:Exception Type: 00000020 Exception Codes: 0x000000008badf00d Exception Note: SIMULATED (this is  ...

  6. iOS常识名词解释 2016/04/05

    Bundle : http://www.cnblogs.com/BigPolarBear/archive/2012/03/28/2421802.html http://blog.sina.com.cn ...

  7. 【精】iOS GCD 具体解释

    一.介绍 1.什么是GCD? Grand Central Dispatch.是苹果公司开发的一套多核编程的底层API. GCD首次公布在Mac OS X 10.6,iOS4及以上也可用.GCD存在于l ...

  8. 关于IOS框架的解释

  9. iOS Core Animation具体解释(四)AutoLayout中的动画

    原创blog.转载请注明出处 blog.csdn.net/hello_hwc 欢迎关注我的iOS SDK具体解释专栏 http://blog.csdn.net/column/details/huang ...

随机推荐

  1. C++中四种强制类型转换方式

    类型转换有c风格的,当然还有c++风格的.c风格的转换的格式很简单(TYPE)EXPRESSION,但是c风格的类型转换有不少的缺点,有的时候用c风格的转换是不合适的,因为它可以在任意类型之间转换,比 ...

  2. TSOJ--方格上的路径

    题目描述: 试求 n × m 的方格图形中,从点 (0, 0) 到点 (n, m) 的最短路径数目. 输入描述: 有多组测试数据.输入的第一行为一个正整数 N,表示接下来有 N 组测试数据. 在接下来 ...

  3. bash快捷键及输入输出重定向

    bash特性之快捷键:     Ctrl+a: 跳转至命令首部     Ctrl+e: 跳转至命令尾部         Ctrl+l: 清屏     Ctrl+c: 中止或取消         Ctr ...

  4. 【LeetCode】Maximum Depth of Binary Tree(二叉树的最大深度)

    这道题是LeetCode里的第104道题. 给出题目: 给定一个二叉树,找出其最大深度. 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数. 说明: 叶子节点是指没有子节点的节点. 示例: 给定 ...

  5. enable apache2 rewrite_mod on ubuntu14.04

    $ cd /etc/apache2/mods-enable $ ln -s rewrite.load ../mods-available/rewrite.load change "Allow ...

  6. Tomcat基础配置(一)

    详情请看散尽浮华的tomcat相关配置技巧梳理 本次只用于自己的查看,谢谢作者的谅解. tomcat常用架构:1)nginx+tomcat:即前端放一台nginx,然后通过nginx反向代理到tomc ...

  7. iOS第三方网络图片加载- SDWebImage笔记(转)

    SDWebImage托管在github上.https://github.com/rs/SDWebImage 这个类库提供一个UIImageView类别以支持加载来自网络的远程图片.具有缓存管理.异步下 ...

  8. 【Luogu】P3567Kur-Couriers(主席树)

    题目链接 数组大小开到一千二百万才过- - 可以把数先离散化再全都加到主席树中. 对于一个区间[from,to] 取中间点mid 看看小于mid的数有多少个,如果个数的两倍<=to-from+1 ...

  9. 常州模拟赛d3t2 灰狼呼唤着同胞

    题目背景 我的母亲柯蒂丽亚,是一个舞者.身披罗纱,一身异国装扮的她,来自灰狼的村子. 曾经在灰狼村子担任女侍的她,被认定在某晚犯下可怕的罪行之后,被赶出了村子. 一切的元凶,都要回到母亲犯下重罪的那一 ...

  10. bzoj2850巧克力王国

    巧克力王国 Time Limit: 60 Sec  Memory Limit: 512 MBSubmit: 861  Solved: 325[Submit][Status][Discuss] Desc ...