都是平时常用的东西
不整理一下的话总感觉有点乱
这三种东西:CGContextRef CGPath UIBezierPath
本质上都是一样的
都是使用 Quartz 来绘画
只不过把绘图操作暴露在不同的 API 层面上
在具体实现上
也会有一些细小的差别
1 - UIBezierPath 方式
首先使用 UIBezierPath 类型绘制
UIBezierPath 包装了Quartz的相关API
自己存在于UIKit中
因此不是基于C的API
而是基于Objective-C对象的
绘制流程 :
- (void)modeUIBezierPath {
// 开启一个与屏幕大小一样的图形上下文
UIGraphicsBeginImageContext(self.view.bounds.size);
UIBezierPath *path = [UIBezierPath bezierPath];
[path appendPath:[UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, 20, 20)]];
[path appendPath:[UIBezierPath bezierPathWithOvalInRect:CGRectMake(80, 0, 20, 20)]];
[path moveToPoint:CGPointMake(100, 50)];
// 注意这里 clockwise 参数是 YES 而不是 NO,如果是 Quartz,需要考虑Y轴翻转的问题传 NO
[path addArcWithCenter:CGPointMake(50, 50) radius:50 startAngle:0 endAngle:M_PI clockwise:YES];
// 可以使用 applyTransform 函数来转移坐标的 Transform
[path applyTransform:CGAffineTransformMakeTranslation(150, 200)];
[[UIColor redColor] setStroke];
[path setLineWidth:2];
[path stroke];
// 从 Context 中获取图像,并显示在界面上
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageView *imgView = [[UIImageView alloc] initWithImage:image];
imgView.backgroundColor = [UIColor blackColor];
[self.view addSubview:imgView];
}
效果 :
2 - CGContextRef 方式 :
- (void)modeCGContextRef {
// 开启一个与屏幕大小一样的图形上下文
UIGraphicsBeginImageContext(self.view.bounds.size);
// 获取当前 CGContextRef
CGContextRef gc = UIGraphicsGetCurrentContext();
// 可以使用 CGContextTranslateCTM 函数来转移坐标的 Transform
CGContextTranslateCTM(gc, 150, 200);
CGContextAddEllipseInRect(gc, CGRectMake(0, 0, 20, 20));
CGContextAddEllipseInRect(gc, CGRectMake(80, 0, 20, 20));
CGContextMoveToPoint(gc, 100, 50);
CGContextAddArc(gc, 50, 50, 50, 0, M_PI, NO);
[[UIColor redColor] setStroke];
CGContextSetLineWidth(gc, 2);
CGContextStrokePath(gc);
// 从 Context 中获取图像,并显示在界面上
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageView *imgView = [[UIImageView alloc] initWithImage:image];
imgView.backgroundColor = [UIColor blackColor];
[self.view addSubview:imgView];
}
效果 :
3 - CGPath 方式 :
- (void)modeCGPath {
// 开始图像绘图
UIGraphicsBeginImageContext(self.view.bounds.size);
// 获取当前 CGContextRef
CGContextRef gc = UIGraphicsGetCurrentContext();
// 可以使用 CGAffineTransformMakeTranslation 函数来转移坐标的 Transform
CGAffineTransform transform = CGAffineTransformMakeTranslation(150, 200);
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddEllipseInRect(path, &transform, CGRectMake(0, 0, 20, 20));
CGPathAddEllipseInRect(path, &transform, CGRectMake(80, 0, 20, 20));
CGPathMoveToPoint(path, &transform, 100, 50);
CGPathAddArc(path, &transform, 50, 50, 50, 0, M_PI, NO);
// 将 CGMutablePathRef 添加到当前 Context 内
CGContextAddPath(gc, path);
[[UIColor redColor] setStroke];
CGContextSetLineWidth(gc, 2);
CGContextStrokePath(gc);
// 从 Context 中获取图像,并显示在界面上
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageView *imgView = [[UIImageView alloc] initWithImage:image];
imgView.backgroundColor = [UIColor blackColor];
[self.view addSubview:imgView];
}
效果 :
另外 :
由于三种方式本质上都是一样的
都是使用Quartz来绘画
使用中很多地方都是互通的
比如 CGPath 和 UIBezierPath 的互转
CGPathRef cgPath = CGPathCreateMutable();
UIBezierPath *bezierPath = [UIBezierPath bezierPathWithCGPath:cgPath];
UIBezierPath *bezierPath = [UIBezierPath bezierPathWithCGPath:cgPath];
CGPathRef cgPath = bezierPath.CGPath;
所以上面任何用 CGPath 的地方都可以换成 UIBezierPath
相反也同理