注意:
本文讲述CGContextRef中相关Transform使用的API,其他类型的Transform会和此类似。
对于CGPath,Path的添加函数中会有CGAfflineTransform参数。如下图:
对于UIBezierPath类型,请使用applyTransform方法。
使用Transform可以帮助我们画出一些有规律且复杂的图像,同时Transform还可以使代码可重复利用性更高,因为我们不需要关注每一个元素的原始坐标,只需要进行Transform,然后执行绘画逻辑就可以。
首先我们会完成这样一个图:
显然这个图可以看做是一个矩形通过不停地旋转而得来的,所以过程就是绘制一个矩形,然后使用CGContextRotateCTM做旋转Transform,接着继续上面的步骤,直到画完为止。
代码如下(在ViewController内):
- (void)viewWillAppear:(BOOL)animated { //开始绘画 UIGraphicsBeginImageContext(self.view.bounds.size); CGContextRef gc = UIGraphicsGetCurrentContext(); //设置颜色 [[UIColor grayColor] setFill]; //设置中心点 CGFloat cenx = CGRectGetMidX(self.view.bounds); CGFloat ceny = CGRectGetMidY(self.view.bounds); CGContextTranslateCTM(gc, cenx, ceny); //不断绘图并设置旋转 for(int i = 0; i < 12; i++) { CGContextAddRect(gc, CGRectMake(-5, 0, 10, 100)); CGContextFillPath(gc); CGContextRotateCTM(gc, 30 * M_PI/180); } //结束绘画 UIImage *destImg = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); //创建UIImageView并显示在界面上 UIImageView *imgView = [[UIImageView alloc] initWithImage:destImg]; [self.view addSubview:imgView]; }
旋转Transform一旦执行坐标就是固定的,所以我们可以随意调节矩形的位置,比如把上面的CGContextAddRect函数调用改成下面这个样子(减少高度,并增加Y轴距离):
CGContextAddRect(gc, CGRectMake(-5, 50, 10, 50));
执行后是这样的:
Transform的效果是可以叠加的,通过不断叠加改变Transform来完成我们的需求,而真正的绘图逻辑则会变得非常简单,实际上我们只需要命令它会画某某某,而某某某具体的位置会被相应的Transform所决定。比如画一个这样的图形,如下图:
完整代码(在ViewController内):
- (void)viewWillAppear:(BOOL)animated { //开始绘画 UIGraphicsBeginImageContext(self.view.bounds.size); CGContextRef gc = UIGraphicsGetCurrentContext(); //设置颜色 [[UIColor blueColor] setFill]; //绘画 CGRect rect = CGRectMake(-5, 0, 10, -50); CGContextTranslateCTM(gc, 0, 60); [self goStraight:gc rect:rect offset:20]; [self turnDirection:gc rect:rect angle:30 count:3]; [self goStraight:gc rect:rect offset:20]; //把旋转点从一个方向移到另外一个方向,注意需要用CGContextScaleCTM把Y轴颠倒 CGContextTranslateCTM(gc, 0, -50); CGContextScaleCTM(gc, 1, -1); [self turnDirection:gc rect:rect angle:30 count:3]; [self goStraight:gc rect:rect offset:20]; //结束绘画 UIImage *destImg = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); //创建UIImageView并显示在界面上 UIImageView *imgView = [[UIImageView alloc] initWithImage:destImg]; [self.view addSubview:imgView]; } //使用CGContextTranslateCTM并连续画5个方格 - (void)goStraight:(CGContextRef)gc rect:(CGRect)rect offset:(CGFloat)offset { for(int i = 0; i < 5; i++) { CGContextTranslateCTM(gc, offset, 0); CGContextFillRect(gc, rect); } } //使用CGContextRotateCTM旋转并画指定个数的方格 - (void)turnDirection:(CGContextRef)gc rect:(CGRect)rect angle:(CGFloat)angle count:(NSInteger)count { for(int i = 0; i < count; i++) { CGContextRotateCTM(gc, angle * M_PI/180); CGContextFillRect(gc, rect); } }