CGPath使用
发布日期:2022-03-18 08:27:35 浏览次数:54 分类:技术文章

本文共 5776 字,大约阅读时间需要 19 分钟。

绘制一条直线

- (void)drawRect:(CGRect)rect {    // Drawing code    CGContextRef ctx = UIGraphicsGetCurrentContext();    CGMutablePathRef path = CGPathCreateMutable();    CGPathMoveToPoint(path, NULL, CGRectGetMinX(rect), CGRectGetMinY(rect));    CGPathAddLineToPoint(path, NULL, CGRectGetMaxX(rect), CGRectGetMaxY(rect));    CGPathCloseSubpath(path);    CGContextAddPath(ctx, path);    CGContextSetStrokeColorWithColor(ctx, [UIColor blueColor].CGColor);    CGContextStrokePath(ctx);    CGPathRelease(path);}

结果如下:

这里写图片描述

Use CGPathCreateCopyByStrokingPath to create a new path by stroking your old path at some width. Then draw your new path using kCGPathFillStroke.

- (void)drawRect:(CGRect)rect {    // Drawing code    CGContextRef context = UIGraphicsGetCurrentContext();    CGMutablePathRef path = CGPathCreateMutable();    CGPathMoveToPoint(path, NULL, 50, 50);    CGPathAddLineToPoint(path, NULL, 200, 200);    CGPathRef thickPath = CGPathCreateCopyByStrokingPath(path, NULL, 10, kCGLineCapButt, kCGLineJoinBevel, 0);    CGContextAddPath(context, thickPath);    CGContextSetStrokeColorWithColor(context, [UIColor blackColor].CGColor);    CGContextSetFillColorWithColor(context, [UIColor blueColor].CGColor);    CGContextSetLineWidth(context, 3);    CGContextDrawPath(context, kCGPathFillStroke);    CGPathRelease(thickPath);    CGPathRelease(path);}

这里写图片描述

绘制圆弧

请参考

使用CGPathAddArc

- (void)drawRect:(CGRect)rect {    // Drawing code    CGContextRef context = UIGraphicsGetCurrentContext();    //创建transform    CGAffineTransform transform = CGAffineTransformMakeTranslation(50, 50);    CGMutablePathRef path = CGPathCreateMutable();    //圆弧    CGPathAddArc(path, &transform, 50, 50, 50, 0, 1.5 * M_PI, NO);    //划线    CGPathMoveToPoint(path, &transform, 50, 0);    CGPathAddLineToPoint(path, &transform, 50, 50);    CGPathAddLineToPoint(path, &transform, 100, 50);    //将CGMutablePathRef添加到当前Context内    CGContextAddPath(context, path);    [[UIColor grayColor] setFill];    [[UIColor blueColor] setStroke];    CGContextSetLineWidth(context, 2);    CGContextDrawPath(context, kCGPathFillStroke);    CGPathRelease(path);}

这里写图片描述

使用CGPathAddArcToPoint

使用CGContextAddArcToPoint函数,我们就可以不去关心太多花弧时的弧度相关数据,而只需要指定矩形的顶点坐标,因为这个弧线是依赖两个顶点坐标所围成的空间的,这正是CGContextAddArcToPoint发挥作用的地方。

- (void)drawRect:(CGRect)rect {    // Drawing code    CGContextRef context = UIGraphicsGetCurrentContext();    //创建用于转移坐标的Transform,这样我们不用按照实际显示做坐标计算    CGAffineTransform transform = CGAffineTransformMakeTranslation(50, 50);    //创建CGMutablePathRef    CGMutablePathRef path = CGPathCreateMutable();    //半径为30    CGFloat radius = 30;    //初始点为(0, 0)    CGPathMoveToPoint(path, &transform, 0, 0);    //右上角和右下角两个点,画出半个圆角    CGPathAddArcToPoint(path, &transform, 100, 0, 100, 100, radius);    //右下角和左下角两个点,画出另外半个圆角    CGPathAddArcToPoint(path, &transform, 100, 100, 0, 100, radius);    //CGPathAddArcToPoint会在交点中停止,所以需要再次调用CGPathAddLineToPoint画出下面的线    CGPathAddLineToPoint(path, &transform, 0, 100);    //将CGMutablePathRef添加到当前Context内    CGContextAddPath(context, path);    [[UIColor grayColor] setFill];    [[UIColor blueColor] setStroke];    CGContextSetLineWidth(context, 2);    CGContextDrawPath(context, kCGPathFillStroke);    CGPathRelease(path);}

这里写图片描述

CGPathRef上绘制渐变颜色

在iOS Core Graphics中绘制渐变颜色主要是通过使用CGContextDraw(xxx)Gradient相关函数,比如,常见的线性渐变就是CGContextDrawLinearGradient函数,这里帖子封装了绘制渐变颜色的具体代码过程,我们拿过来直接用,只不过原帖代码是用CGContextAddRect画了一个矩形,我们改一下去画CGPathRef。这里无论是什么形状其实无所谓,原理都是用来做Clip,所以需要在CGContextClip函数前调用CGContextAddPath函数把CGPathRef加入到Context中。

另外一个需要注意的地方是渐变的方向,方向是由两个点控制的,点的单位就是坐标。因此需要正确从CGPathRef中找到正确的点,方法当然有很多种看具体实现,本例中,我就是简单得通过调用CGPathGetBoundingBox函数,返回CGPathRef的矩形区域,然后根据这个矩形取两个点,读者可以根据自行需求修改具体代码。

OK,把代码封装成一个方法,类似这样:

/** * 修改自http://www.raywenderlich.com/32283/core-graphics-tutorial-lines-rectangles-and-gradients */- (void)drawLinearGradient:(CGContextRef)context                      path:(CGPathRef)path                startColor:(CGColorRef)startColor                  endColor:(CGColorRef)endColor{    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();    CGFloat locations[] = { 0.0, 1.0 };    NSArray *colors = @[(__bridge id) startColor, (__bridge id) endColor];    CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef) colors, locations);    CGRect pathRect = CGPathGetBoundingBox(path);    //具体方向可根据需求修改    CGPoint startPoint = CGPointMake(CGRectGetMidX(pathRect), CGRectGetMinY(pathRect));    CGPoint endPoint = CGPointMake(CGRectGetMidX(pathRect), CGRectGetMaxY(pathRect));    CGContextSaveGState(context);    CGContextAddPath(context, path);    CGContextClip(context);    CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);    CGContextRestoreGState(context);    CGGradientRelease(gradient);    CGColorSpaceRelease(colorSpace);}

接下来就可以使用了,示例代码:

- (void)viewDidLoad {    [super viewDidLoad];    //创建CGContextRef    UIGraphicsBeginImageContext(self.view.bounds.size);    CGContextRef gc = UIGraphicsGetCurrentContext();    //创建CGMutablePathRef    CGMutablePathRef path = CGPathCreateMutable();    //绘制Path    CGRect rect = CGRectInset(self.view.bounds, 30, 30);    CGPathMoveToPoint(path, NULL, CGRectGetMinX(rect), CGRectGetMinY(rect));    CGPathAddLineToPoint(path, NULL, CGRectGetMidX(rect), CGRectGetHeight(rect));    CGPathAddLineToPoint(path, NULL, CGRectGetWidth(rect), CGRectGetHeight(rect) * 2 / 3);    CGPathCloseSubpath(path);    //绘制渐变    [self drawLinearGradient:gc path:path startColor:[UIColor greenColor].CGColor endColor:[UIColor redColor].CGColor];    //注意释放CGMutablePathRef    CGPathRelease(path);    //从Context中获取图像,并显示在界面上    UIImage *img = UIGraphicsGetImageFromCurrentImageContext();    UIGraphicsEndImageContext();    UIImageView *imgView = [[UIImageView alloc] initWithImage:img];    [self.view addSubview:imgView];}

效果如下:

这里写图片描述

转载地址:https://windzen.blog.csdn.net/article/details/49278133 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:iOS开源项目学习—— AFNetworking
下一篇:iOS开源项目学习——开源中国iOS客户端

发表评论

最新留言

路过按个爪印,很不错,赞一个!
[***.219.124.196]2024年03月26日 03时38分52秒