绘制文本

CGContextRef为绘制文字提供了如下函数。

CGAffineTransform CGContextGetTextMatrix(CGContextRef c):获取当前对文本执行变换的变换矩阵。

CGPoint CGContextGetTextPosition(CGContextRef c):获取该CGContextRef中当前绘制文本的位置。

CGContextSelectFont(CGContextRef c, const char *name, CGFloat size, CGTextEncoding textEncoding):设置该CGContextRef当前绘制文本的字体、字体大小。

void CGContextSetCharacterSpacing(CGContextRef c, CGFloat spacing):设置该CGContextRef中绘制文本的字符间距。

void CGContextSetFont(CGContextRef c, CGFontRef font):设置该CGContextRef中绘制文本的字体。

void CGContextSetFontSize(CGContextRef c, CGFloat size):设置该CGContextRef中绘制文本的字体大小。

CGContextSetTextDrawingMode(CGContextRef c, CGTextDrawingMode mode):设置该CGContextRef绘制文本的绘制模式。该函数支持kCGTextFill、kCGTextStroke、kCGTextFillStroke等绘制模式。

void CGContextSetTextMatrix(CGContextRef c, CGAffineTransform t):设置对将要绘制的文本执行指定的变换。

CGContextSetTextPosition(CGContextRef c , CGFloat x, CGFloat y):设置CGContextRef的一个文本的绘制位置。

void CGContextShowText(CGContextRef c,
const char *string,
size_t length):控制CGContextRef在当前绘制点绘制指定文本。

void CGContextShowTextAtPoint (CGContextRef c,
CGFloat x,
CGFloat y,
 const char *string,
 size_t length):控制CGContextRef在指定绘制点绘制指定文本。

除此之外,系统还为NSString提供了一个UIStringDrawing分类,通过该分类为NSString增加了drawAtPoint:withAttributes:、drawInRect:withAttributes:等绘制方法,通过这些绘制方法可以更方便地绘制字符串。

总结起来,使用CGContextRef绘制文本的步骤如下。

获取绘图的CGContextRef。

设置绘制文本的相关属性,例如,绘制文本所用的绘制方式、字体大小、字体名称等。

如果只是绘制不需要进行变换的文本,直接调用NSString的drawAtPoint:withAttributes:、drawInAttributes:withFont:等方法绘制即可。如果需要对绘制的文本进行变换,则需要先调用CGContextSetTextMatrix()函数设置变换矩阵,再调用CGContextShowTextAtPoint()方法绘制文本。

下面的程序示范了如何利用Quartz 2D绘制文本。首先创建一个Single View Application,该Application包含一个应用程序委托代理类、一个视图控制器和配套的Storyboard界面设计文件。将该界面设计文件中最大的View改为使用自定义的FKTextView类,并向该界面设计文件添加两个UISlider控件。为了让这两个UISlider控件控制文本的缩放和旋转角度,将控制缩放的UISlider的最小值、最大值分别设置为0.1、5;将控制旋转的UISlikder的最小值、最大值设分别为-90、90,程序为两个UISlider的Value Changed事件分别绑定scaleChanged:和rotateChanged: IBActino方法。

下面是该应用的视图控制器类的实现代码。

程序清单:codes/12/12.2/DrawTextTest/DrawTextTest/FKViewController.m
 

 
 
  1. @implementation FKViewController  
  2. - (void)viewDidLoad  
  3. {  
  4.     [super viewDidLoad];  
  5.     self.view.backgroundColor = [UIColor whiteColor];  
  6. }  
  7. - (IBAction)scaleChanged:(id)sender  
  8. {  
  9.     // 修改FKTextView的scaleRate属性  
  10.     ((FKTextView*)self.view).scaleRate = ((UISlider*)sender).value;  
  11. }  
  12. - (IBAction)rotateChanged:(id)sender  
  13. {  
  14.     // 修改FKTextView的rotateAngle属性  
  15.     ((FKTextView*)self.view).rotateAngle = ((UISlider*)sender).value;  
  16. }  
  17. @end 

从上面的控制器代码可以看出,当用户拖动界面的UISlider时,视图控制器中的监听器方法就会改变FKTextView控件的scaleRate、rotateAngle属性。当这些属性被修改时,FKTextView就会使用特定的缩放比、旋转角重绘文本。下面是FKTextView类的实现代码。

程序清单:codes/12/12.2/DrawTextTest/DrawTextTest/FKTextView.m
 

 
 
  1. @implementation FKTextView  
  2. - (void)setScaleRate:(CGFloat)scaleRate  
  3. {  
  4.     if(_scaleRate != scaleRate)  
  5.     {  
  6.         _scaleRate = scaleRate;   
  7.         [self setNeedsDisplay];  // 通知该控件重绘自己  
  8.     }  
  9. }  
  10. - (void)setRotateAngle:(CGFloat)rotateAngle  
  11. {  
  12.     if(_rotateAngle != rotateAngle)  
  13.     {  
  14.         _rotateAngle = rotateAngle;  
  15.         [self setNeedsDisplay];  // 通知该控件重绘自己  
  16.     }  
  17. }  
  18. // 重写该方法绘制该控件  
  19. - (void)drawRect:(CGRect)rect  
  20. {     
  21.     CGContextRef ctx = UIGraphicsGetCurrentContext();  // 获取该控件的绘图CGContextRef  
  22.     CGContextSetCharacterSpacing (ctx, 4);  // 设置字符间距  
  23.     CGContextSetRGBFillColor (ctx, 1, 0, 1, 1);  // 设置填充颜色  
  24.     CGContextSetRGBStrokeColor (ctx, 0, 0, 1, 1);  // 设置线条颜色  
  25.     CGContextSetTextDrawingMode (ctx, kCGTextFill);  // 设置使用填充模式绘制文字  
  26.     // 绘制文字   
  27.     [@"疯狂iOS讲义" drawAtPoint:CGPointMake(10 ,20)  
  28.         withAttributes:[NSDictionary dictionaryWithObjectsAndKeys:  
  29.         [UIFont fontWithName:@"Arial Rounded MT Bold" size: 45],  
  30.         NSFontAttributeName,  
  31.         [UIColor magentaColor] , NSForegroundColorAttributeName , nil]];  
  32.     // 设置使用描边模式绘制文字  
  33.     CGContextSetTextDrawingMode (ctx, kCGTextStroke);  
  34.     // 绘制文字  
  35.     [@"疯狂Android讲义" drawAtPoint:CGPointMake(10 ,80)  
  36.         withAttributes:[NSDictionary dictionaryWithObjectsAndKeys:  
  37.         [UIFont fontWithName:@"Heiti SC" size: 40],NSFontAttributeName,  
  38.         [UIColor blueColor] , NSForegroundColorAttributeName , nil]];  
  39.     // 设置使用填充、描边模式绘制文字  
  40.     CGContextSetTextDrawingMode (ctx, kCGTextFillStroke);  
  41.     // 绘制文字  
  42.     [@"疯狂Ajax讲义" drawAtPoint:CGPointMake(10 ,130)  
  43.         withAttributes:[NSDictionary dictionaryWithObjectsAndKeys:  
  44.         [UIFont fontWithName:@"Heiti SC" size: 50], NSFontAttributeName,  
  45.         [UIColor magentaColor] , NSForegroundColorAttributeName , nil]];  
  46.     // 定义一个垂直镜像的变换矩阵  
  47.     CGAffineTransform yRevert = CGAffineTransformMake(1, 0, 0, -1, 0, 0);  
  48.     // 设置绘制文本的字体和字体大小  
  49.     CGContextSelectFont (ctx, "Courier New" , 40, kCGEncodingMacRoman);  
  50.     // 为yRevert变换矩阵根据scaleRate添加缩放变换矩阵  
  51.     CGAffineTransform scale = CGAffineTransformScale(yRevert,  
  52.         self.scaleRate, self. scaleRate);  
  53.     // 为scale变换矩阵根据rotateAngle添加旋转变换矩阵  
  54.     CGAffineTransform rotate = CGAffineTransformRotate(scale,   
  55.         M_PI * self.rotateAngle / 180);  
  56.     CGContextSetTextMatrix(ctx, rotate);  // 对CGContextRef绘制文字时应用变换  
  57.     CGContextShowTextAtPoint(ctx, 50, 300, "crazyit.org", 11);  // 绘制文本  
  58. }  
  59. @end 

上面的程序中,前三行粗体字代码直接调用了NSString的drawAtPoint:withAttributes:方法进行绘制--这是一种非常简单的绘制方式。

接下来需要对绘制的文本执行坐标变换,因此程序中先用CGAffineTransformMake()函数定义了一个变换矩阵:(1, 0, 0, -1, 0, 0),该变换矩阵将会对绘制的文本做垂直镜像。此处这么做的原因是因为Quartz 2D本身的坐标系统与UIView控件绘图的坐标系统并不相同,Quartz 2D为了照顾开发者的习惯,已经对坐标系统做过变换,但它在处理文本变换时少了一次垂直镜像变换,导致绘制出来的文本总是上下颠倒的。为了解决这个问题,笔者先对文本做了一次垂直镜像变换。


关于坐标变换的详细理论,后面会详细阐述,读者可参考相关内容。

然后利用CGAffineTransformScale()、CGAffineTransformRotate()增加了缩放、旋转变换,程序最后一行粗体字代码调用CGContextShowTextAtPoint()方法绘制了文本,该文本将会带有缩放和旋转效果。

上面的程序中,在绘制文本时,使用了大量iOS支持的字体,如果读者需要获取iOS支持的所有字体,可调用UIFont类的familyNames类方法,该方法返回一个数组,该数组包含iOS所支持的全部字体。

编译、运行该程序,用户即可通过拖动界面上的UISlider控件来改变文本的缩放、旋转,效果如图12.5所示。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值