文本绘制在开发客户端程序中是一个比较常用的功能,可分为采用控件和直接绘制两种方式。

采用控件的方式比较简便,添加一个比如UILabel对象,然后设置相关属性就好了。但这种方式局限性也比较大。

直接绘制相对比较自由,但也分为使用NSString和Quartz 2D两种方式。

NSString有一组绘制文本的函数,drawAtPoint是其中一个。使用方式如下:

  1. 1 NSString* text = @"This is English text(NSString).";
  2. 2 [text drawAtPoint:CGPointMake(0, 0) withFont:[UIFont systemFontOfSize:20]];

接口还是比较简单的,也可以画中文。

  1. 1 text = @"这是中文文本(NSString)。";
  2. 2 [text drawAtPoint:CGPointMake(0, 50) withFont:[UIFont systemFontOfSize:20]];

Quartz 2D中文本绘制稍微复杂一点,因为它提供的接口是C形式的,而不是OC的。先来看看如何画英文:

  1. 1 CGContextSetTextMatrix(context, CGAffineTransformMakeScale(1.0, -1.0));
  2. 2 CGContextSelectFont(context, "Helvetica", 20, kCGEncodingMacRoman);
  3. 3 const char* str = "This is English text(Quartz 2D).";
  4. 4 CGContextShowTextAtPoint(context, 0, 100, str, strlen(str));

CGContextSetTextMatrix是调整坐标系,防止文字倒立。
我们用同样的方法尝试绘制中文。

  1. 1 const char* str1 = "这是中文文本(Quartz 2D)。";
  2. 2 CGContextShowTextAtPoint(context, 0, 150, str1, strlen(str1));

但屏幕上显示的是乱码。为什么呢?

Quartz 2D Programming Guide中有这样一段说明:

To set the font to a text encoding other than MacRoman, you can use the functions CGContextSetFont and CGContextSetFontSize. You must supply a CGFont object to the function CGContextSetFont. You call the function CGFontCreateWithPlatformFont to obtain a CGFont object from an ATS font. When you are ready to draw the text, you use the function CGContextShowGlyphsAtPoint rather than CGContextShowTextAtPoint.

人家说了,如果编码超出MacRoman的范围,你要使用CGContextShowGlyphsAtPoint来绘制。这个函数和CGContextShowTextAtPoint类似,也是5个参数,而且只有第四个参数不同,是字形数组(可能描述的不准确)CGGlyph glyphs[],这个东西如何得到呢?在CoreText frameork(support iOS3.2 and later)提供了这样的接口。代码如下:

  1. 1 UniChar *characters;
  2. 2 CGGlyph *glyphs;
  3. 3 CFIndex count;
  4. 4
  5. 5 CTFontRef ctFont = CTFontCreateWithName(CFSTR("STHeitiSC-Light"), 20.0, NULL);
  6. 6 CTFontDescriptorRef ctFontDesRef = CTFontCopyFontDescriptor(ctFont);
  7. 7 CGFontRef cgFont = CTFontCopyGraphicsFont(ctFont,&ctFontDesRef );
  8. 8 CGContextSetFont(context, cgFont);
  9. 9 CFNumberRef pointSizeRef = (CFNumberRef)CTFontDescriptorCopyAttribute(ctFontDesRef,kCTFontSizeAttribute);
  10. 10 CGFloat fontSize;
  11. 11 CFNumberGetValue(pointSizeRef, kCFNumberCGFloatType,&fontSize);
  12. 12 CGContextSetFontSize(context, fontSize);
  13. 13 NSString* str2 = @"这是中文文本(Quartz 2D)。";
  14. 14 count = CFStringGetLength((CFStringRef)str2);
  15. 15 characters = (UniChar *)malloc(sizeof(UniChar) * count);
  16. 16 glyphs = (CGGlyph *)malloc(sizeof(CGGlyph) * count);
  17. 17 CFStringGetCharacters((CFStringRef)str2, CFRangeMake(0, count), characters);
  18. 18 CTFontGetGlyphsForCharacters(ctFont, characters, glyphs, count);
  19. 19 CGContextShowGlyphsAtPoint(context, 0, 200, glyphs, str2.length);
  20. 20
  21. 21 free(characters);
  22. 22 free(glyphs);

STHeitiSC-Light是系统自带的一种中文字体。

这样写的话中文就能正常绘制出来了。

下图是显示效果,分别对应上面的5个示例。

iOS上文本绘制的几种方法的更多相关文章

  1. Android(java)学习笔记106:Android设置文本颜色的4种方法

    1. Android设置文本颜色的4种方法: (1)利用系统自带的颜色类: tv.setTextColor(android.graphics.Color.RED); (2)数字颜色表示: tv.set ...

  2. 利用css去除input按钮上的文字的几种方法

    相信很多时候input上的文字困扰着web前端开发者,必须要通过修改html代码中的value值才能清空按钮上的文字,但很多人不愿意去动html代码,一方面麻烦,另外主要的原因还在于保留文字对seo有 ...

  3. html实现返回上一页的几种方法(javaScript:history.go(-1);)

    html实现返回上一页的几种方法(javaScript:history.go(-1);) 一.总结: 1.javaScript:history.go(-1); 二.方法 1.通过超链接返回到上一页 & ...

  4. (转载)ios关闭虚拟键盘的几种方法

    在iOS应用开发中,有三类视图对象会打开虚拟键盘,进行输入操作,但如何关闭虚拟键盘,却没有提供自动化的方法.这个需要我们自己去实现.这三类视图对象分别是UITextField,UITextView和U ...

  5. IOS中延迟执行的几种方法

    前几天去国美在线面试,就遇到了上面的问题,当时是笔试,只写出来了第一种方法,现在整理了一下. //1.performSelector方法:在当前线程中执行的方法,使用默认模式,并延迟执行@select ...

  6. IOS中Json解析的四种方法

    作为一种轻量级的数据交换格式,json正在逐步取代xml,成为网络数据的通用格式. 有的json代码格式比较混乱,可以使用此“http://www.bejson.com/”网站来进行JSON格式化校验 ...

  7. 在CentOS上安装Python3的三种方法

    Centos7默认自带了Python2.7版本,但是因为项目需要使用Python3.x你可以按照此文的三个方法进行安装. 注:本文示例安装版本为Python3.5, 一.Python源代码编译安装 安 ...

  8. iOS 创建单例的两种方法

    创建一个单例很多办法.我先列举一个苹果官方文档中的写法. [cpp] view plaincopy static AccountManager *DefaultManager = nil; + (Ac ...

  9. net上传文件的三种方法

    ASP.NET依托.net framework类库,封装了大量的功能,使得上传文件非常简单,主要有以下三种基本方法. 方法一:用Web控件FileUpload,上传到网站根目录. Test.aspx关 ...

随机推荐

  1. Codeforces Round #316 div2

    一场充满血腥hack之战!!! Problem_A: 题意: n个候选人在m个城市进行投票,每个城市选出票数最多的一个候选人为城市候选人,如果票数相同,则取编号小的候选人. 再从这m个城市候选人中选出 ...

  2. C# 两个获得程序运行路径的函数

    EXE文件的存储路径,不太受调用时环境变量的影响: Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Lo ...

  3. 自定义scrollbar

    Chrome ::-webkit-scrollbar 整体部分 ::-webkit-scrollbar-track 轨道 ::-webkit-scrollbar-track-piece 内层轨道 :: ...

  4. nutch 很多url unfetched的原因

    bin/hadoop jar apache-nutch-1.7.job org.apache.nutch.crawl.CrawlDbReader crawl/crawldb -stats -sort ...

  5. SPRING IN ACTION 第4版笔记-第一章-002-DI介绍

    一. 1.knight.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns=&qu ...

  6. 集合ArrayList双色球练一练(自己的方法,太麻烦)

    namespace 集合__双色球练一练{    class Program    {        static void Main(string[] args)        {        / ...

  7. 读完了简明Python教程(a bite of Python)

    因为学过C/C++,简明教程里很多共通的地方一看就明白. 明天做书最后的练习. <--! 代码占位 -->

  8. asp.net EasyUI DataGrid 实现增删改查

    转自:http://www.cnblogs.com/create/p/3410314.html 前台代码: <!DOCTYPE html> <html xmlns="htt ...

  9. 【性能测试】【Jmeter】学习(3)——查看测试结果

    监听器——聚合报告 聚合报告添加步骤:(右键点击每一个操作步骤--->“添 加”---->“监听器”---->“聚合报告”) Label:每个 JMeter 的 element(例如 ...

  10. java基础(十五)集合(二)

    这里有我之前上课总结的一些知识点以及代码大部分是老师讲的笔记 个人认为是非常好的,,也是比较经典的内容,真诚的希望这些对于那些想学习的人有所帮助! 由于代码是分模块的上传非常的不便.也比较多,讲的也是 ...