使用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);
}
}