UIBezierPath
贝塞尔曲线
贝塞尔曲线,又称贝兹曲线或贝济埃曲线,是应用于二维图形应用程序的数学曲线。一般的矢量图形软件通过它来精确画出曲线,贝兹曲线由线段与节点组成,节点是可拖动的支点,线段像可伸缩的皮筋,我们在绘图工具上看到的钢笔工具就是来做这种矢量曲线的
下面分别是 一阶、二阶、三阶、高阶 曲线图
贝塞尔曲线的应用
贝塞尔曲线在iOS中有一个对应的类,叫做UIBezierPath
,UIBezierPath
是Core Graphics
框架关于路径的封装
UIBezierPath
通常与CAShapeLayer
配合使用。CAShapeLayer
继承自CALayer
,它拥有CALayer
的所有属性。UIBezierPath
为CAShapeLayer
提供路径, CAShapeLayer
在提供的路径中进行渲染, 绘制出图形
属性介绍
CGPath:将UIBezierPath类转换成CGPath,类似于UIColor的CGColor
empty:只读类型,路径上是否有有效的元素
bounds:和view的bounds是不一样的,它获取path的X坐标、Y坐标、宽度,但是高度为0
currentPoint:当前path的位置,可以理解为path的终点
lineWidth:path宽度
lineCapStyle:path端点样式,有3种样式
lineJoinStyle:拐角样式
miterLimit:最大斜接长度(只有在使用kCGLineJoinMiter是才有效), 边角的角度越小,斜接长度就会越大
为了避免斜接长度过长,使用lineLimit属性限制,如果斜接长度超过miterLimit,边角就会以KCALineJoinBevel类型来显示
flatness:弯曲路径的渲染精度,默认为0.6,越小精度越高,相应的更加消耗性能。
usesEvenOddFillRule:单双数圈规则是否用于绘制路径,默认是NO。
- UIRectCorner:角
创建在rect内的矩形:
(instancetype)bezierPathWithRect:(CGRect)rect:
创建在rect里的内切曲线:
(instancetype)bezierPathWithOvalInRect:(CGRect)rect:
创建带有圆角的矩形,当矩形变成正圆的时候,Radius就不再起作用:
+ (instancetype)bezierPathWithRoundedRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius
设定特定的角为圆角的矩形:
(instancetype)bezierPathWithRoundedRect:(CGRect)rect byRoundingCorners:(UIRectCorner)corners cornerRadii:(CGSize)cornerRadii
创建圆弧
(instancetype)bezierPathWithArcCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise
通过已有路径创建路径:
UIBezierPath *path_A = [UIBezierPath bezierPath]; [path_A moveToPoint:CGPointMake(200, 50)]; [path_A addLineToPoint:CGPointMake(250, 100)]; path_A.lineWidth = 5.0f; UIBezierPath *path_B = [UIBezierPath bezierPathWithCGPath:path_A.CGPath]; [path_B stroke];复制代码
创建二次贝塞尔曲线
UIBezierPath *path = [UIBezierPath bezierPath]; [path moveToPoint:CGPointMake(200, 300)]; [path addQuadCurveToPoint:endPoint controlPoint:controlPoint]; [path stroke];复制代码
创建三次贝塞尔曲线
UIBezierPath *path = [UIBezierPath bezierPath]; [path moveToPoint:CGPointMake(200, 200)]; [path addCurveToPoint:endPoint controlPoint1:controlPoint1 controlPoint2:controlPoint2]; [path stroke];复制代码
添加圆弧
/** * 添加圆弧 * @param center 圆点 * @param radius 半径 * @param startAngle 起始位置 * @param endAngle 结束为止 * @param clockwise 是否顺时针方向 */ - (void)createAddArcWithCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise{ UIBezierPath *path = [UIBezierPath bezierPath]; [path moveToPoint:CGPointMake(200, 400)]; [path addLineToPoint:CGPointMake(225, 410)]; [path addArcWithCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:clockwise]; [path closePath]; [path removeAllPoints]; [path stroke]; }复制代码
追加路径
/** * 追加路径 */ - (void)appendPath{ UIBezierPath *path_A = [UIBezierPath bezierPath]; [path_A moveToPoint:CGPointMake(200, 500)]; [path_A addLineToPoint:CGPointMake(225, 410)]; UIBezierPath *path_B = [UIBezierPath bezierPath]; [path_B moveToPoint:CGPointMake(200, 600)]; [path_B addLineToPoint:CGPointMake(225, 500)]; [path_A appendPath:path_B]; [path_A stroke]; }复制代码
创建翻转路径,即起点变成终点,终点变成起点
- (void)createReversingPath{ UIBezierPath *path = [UIBezierPath bezierPath]; [path moveToPoint:CGPointMake(50, 50)]; [path addLineToPoint:CGPointMake(100, 50)]; path.lineWidth = 5.0f; NSLog(@"%@",NSStringFromCGPoint(path.currentPoint)); UIBezierPath *path_b = [path bezierPathByReversingPath]; NSLog(@"%@",NSStringFromCGPoint(path_b.currentPoint)); [path_b stroke]; }复制代码
路径进行仿射变换
- (void)createApplyTransform{ CGAffineTransform transform = CGAffineTransformMakeScale(2, 2); UIBezierPath *path = [UIBezierPath bezierPath]; [path moveToPoint:CGPointMake(10, 50)]; [path addLineToPoint:CGPointMake(100, 50)]; [path applyTransform:transform]; path.lineWidth = 5.0f; [path stroke]; }复制代码
创建虚线
/** * 创建虚线 * @param pattern C类型线性数据 * @param count pattern中数据个数 * @param phase 起始位置 */ - (void)createLineDash:(nullable const CGFloat *)pattern count:(NSInteger)count phase:(CGFloat)phase{ UIBezierPath *path = [UIBezierPath bezierPath]; [path moveToPoint:CGPointMake(50, 50)]; [path addLineToPoint:CGPointMake(100, 50)]; [path setLineDash:pattern count:count phase:0.0]; [path stroke]; }复制代码
设置颜色
- (void)setLineColor:(UIColor *)lineColor fillColor:(UIColor *)fillColor{ UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(100, 100, 100, 100)]; [lineColor setStroke]; [fillColor setFill]; [path stroke]; [path fill]; }复制代码
设置描边混合模式
- (void)setFillWithBlendMode{ UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(100, 100, 100, 100)]; [[UIColor redColor] setFill]; [path fillWithBlendMode:kCGBlendModeSaturation alpha:0.6]; [path fill]; } - (void)setStrokeWithBlendMode{ UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(100, 100, 100, 100)]; [[UIColor greenColor] setStroke]; path.lineWidth = 10.0f; [path strokeWithBlendMode:kCGBlendModeSaturation alpha:1.0]; [path stroke]; }复制代码
修改当前图形上下文的绘图区域可见,随后的绘图操作导致呈现内容只有发生在指定路径的填充区域
- (void)createAddClip{ UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(100, 100, 100, 100)]; [[UIColor greenColor] setStroke]; [path addClip]; [path stroke]; }
作者:Mr_JIE
链接:https://juejin.cn/post/7022540680006205448