CAShapeLayer继承CALayer
CAShapeLayer *square = [[CAShapeLayer alloc] init];
square.frame = CGRectMake(20, 20, 100, 100);
square.backgroundColor = [UIColor blackColor].CGColor;
[self.view.layer addSublayer:square];
显示:,这个和CALayer一样,没有多大作用。
接下来 将UIBezierPath对象 转化为CGPathRef 对象,赋值给CAShapeLayer的path属性即可,即可画出各种线条和图形。
结合UIBezierPath 与 CAShapeLayer 画图:
-
矩形:
UIBezierPath *bezierPath = [UIBezierPath bezierPathWithRect:CGRectMake(40, 40, 100, 100)];
CAShapeLayer *square = [CAShapeLayer layer];
square.path = bezierPath.CGPath;
square.fillColor = [UIColor whiteColor].CGColor; // 内部填充色
square.strokeColor = [UIColor blackColor].CGColor; // 线的颜色
[self.view.layer addSublayer:square];
-
椭圆或圆:
OR
画椭圆或圆的UIBezierPath相关方法:(生成一个矩形的内切椭圆UIBezierPath对象,如果矩形是正方形,就为内切圆)
+ (instancetype)bezierPathWithOvalInRect:(CGRect)rect:
// 矩形的内切椭圆
UIBezierPath *ovalPath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(40, 40, 120, 80)];
CAShapeLayer *layer = [CAShapeLayer layer];
layer.path = ovalPath.CGPath;
layer.lineWidth = 2.f; // 边线的宽度
layer.strokeColor = [UIColor redColor].CGColor;
// layer.fillColor // 默认为blackColor
[self.view.layer addSublayer:layer];
// 正方形的内切圆
UIBezierPath *circlePath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(40, 40, 100, 100)];
CAShapeLayer *layer = [CAShapeLayer layer];
layer.path = circlePath.CGPath;
layer.lineWidth = 2.f; // 边线的宽度
layer.strokeColor = [UIColor redColor].CGColor;
layer.fillColor = [UIColor clearColor].CGColor;
[self.view.layer addSublayer:layer];
-
折线:
画折线的UIBezierPath相关方法:
+ (instancetype)bezierPath -- 生成一个UIBezierPath对象, 多用于画 不规则曲线 或 多边图形
- (void)moveToPoint:(CGPoint)point -- 添加路径起点
- (void)addLineToPoint:(CGPoint)point -- 添加路径起点外的其他点
// 线的路径
UIBezierPath *linePath = [UIBezierPath bezierPath];
// 起点
[linePath moveToPoint:CGPointMake(40, 40)];
// 其它点
[linePath addLineToPoint:CGPointMake(120, 80)];
[linePath addLineToPoint:CGPointMake(140, 60)];
CAShapeLayer *layer = [CAShapeLayer layer];
layer.path = linePath.CGPath;
layer.strokeColor = [UIColor redColor].CGColor;
layer.fillColor = [UIColor clearColor].CGColor;
[self.view.layer addSublayer:layer];
当 layer.fillColor = [UIColor whiteColor].CGColor; 有填充色后:
证明了:CAShapeLayer依附于一个给定的path,必须给与path,而且,即使path不完整也会自动首尾相接。
-
多边形(三角形):
UIBezierPath相关方法:
- (void)closePath -- 封闭曲线(连接曲线的起点和终点形成封闭曲线
// 线的路径
UIBezierPath *trianglePath = [UIBezierPath bezierPath];
[trianglePath moveToPoint:CGPointMake(40, 60)];
[trianglePath addLineToPoint:CGPointMake(120, 80)];
[trianglePath addLineToPoint:CGPointMake(80, 120)];
// 封闭曲线
[trianglePath closePath];
CAShapeLayer *layer = [CAShapeLayer layer];
layer.path = trianglePath.CGPath;
layer.strokeColor = [UIColor redColor].CGColor;
layer.fillColor = [UIColor clearColor].CGColor;
[self.view.layer addSublayer:layer];
-
圆角矩形:
画圆角矩形的UIBezierPath相关方法:
+ (instancetype)bezierPathWithRoundedRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius -- 生成一个自定义圆角大小的矩形UIBezierPath对象
当 rect 中 width = height = cornerRadius * 2 , 这不就又是一个圆了;
UIView *contentView = [[UIView alloc] initWithFrame:CGRectMake(40, 40, 120, 100)];
contentView.backgroundColor = [UIColor purpleColor];
[self.view addSubview:contentView];
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:contentView.bounds cornerRadius:20.f];
CAShapeLayer *layer = [CAShapeLayer layer];
layer.path = path.CGPath;
layer.strokeColor = [UIColor redColor].CGColor;
contentView.layer.mask = layer; // layer的mask属性,添加蒙版
-
单角的圆角矩形(左上角):
画单角的圆角矩形的UIBezierPath相关方法:
+ (instancetype)bezierPathWithRoundedRect:(CGRect)rect byRoundingCorners:(UIRectCorner)corners cornerRadii:(CGSize)cornerRadii
为矩形的某一个角添加自定义大小的圆角(当自定义的圆角大小超过矩形宽或高的一半是,自动取矩形宽或高的一半作为圆角大小)
如果想对视图单个角切圆角,和圆切圆角相同只需将UIBezierPath对象添加为mask即可。
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(40, 40, 100, 100) byRoundingCorners:UIRectCornerTopLeft cornerRadii:CGSizeMake(20, 0)];
CAShapeLayer *layer = [CAShapeLayer layer];
layer.path = path.CGPath;
layer.lineWidth = 2.f;
layer.strokeColor = [UIColor redColor].CGColor;
layer.fillColor = [UIColor whiteColor].CGColor;
[self.view.layer addSublayer:layer];
如果作做多个圆角的矩形:
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(40, 40, 100, 100)
byRoundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight
cornerRadii:CGSizeMake(20, 0)];
-
圆弧:
画圆弧的UIBezierPath相关方法:
+ (instancetype)bezierPathWithArcCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise
center:圆弧的中心,相对所在视图; radius:圆弧半径; startAngle:起始点的角度(相对角度坐标系0); endAngle:结束点的角度(相对角度坐标系0); clockwise:是否为顺时针方向。
- (void)addArcWithCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise
在原有的线上添加一条弧线 。center:圆弧的中心,相对所在视图; radius:圆弧半径; startAngle:起始点的角度(相对角度坐标系0); endAngle:结束点的角度(相对角度坐标系0); clockwise:是否为顺时针方向。
// 初始化 画圆弧
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(200, 200) radius:50.f startAngle:0 endAngle:M_PI_2 clockwise:YES];
// 添加一条线
[path addLineToPoint:CGPointMake(100, 250)];
// 再画 1/4 圆弧
[path addArcWithCenter:CGPointMake(100, 200) radius:50.f startAngle:M_PI_2 endAngle:M_PI clockwise:YES];
CAShapeLayer *layer = [CAShapeLayer layer];
layer.path = path.CGPath;
layer.lineWidth = 2.f;
layer.strokeColor = [UIColor redColor].CGColor;
layer.fillColor = [UIColor clearColor].CGColor;
[self.view.layer addSublayer:layer];
-
贝塞尔曲线
二次贝塞尔曲线:
二次贝赛尔曲线相关方法:
- (void)addQuadCurveToPoint:(CGPoint)endPoint controlPoint:(CGPoint)controlPoint
贝塞尔二次曲线,起点用 moveToPoint方法给出;endPoint:贝赛尔曲线终点;controlPoint:控制点;曲线是由起点趋向控制点最后到达终点(不会经过控制点)的曲线。控制点决定曲线的起始方向,起点和终点的距离决定曲线趋向控制点的程度。
二次贝塞尔曲线示意图:
三次贝塞尔曲线:
三次贝塞尔曲线相关方法:
- (void)addCurveToPoint:(CGPoint)endPoint controlPoint1:(CGPoint)controlPoint1 controlPoint2:(CGPoint)controlPoint2
三次贝赛尔曲线,起点用 moveToPoint方法给出;endPoint:贝赛尔曲线终点;controlPoint1:控制点1;controlPoint2:控制点2
三次贝塞尔曲线示意图:
// 一条 二次贝赛尔曲线 -- 参照线(红线)
UIBezierPath *path1 = [UIBezierPath bezierPath];
[path1 moveToPoint:CGPointMake(80, 80)];
[path1 addQuadCurveToPoint:CGPointMake(280, 120) controlPoint:CGPointMake(120, 40)];
CAShapeLayer *layer1 = [CAShapeLayer layer];
layer1.path = path1.CGPath;
layer1.strokeColor = [UIColor redColor].CGColor;
layer1.fillColor = [UIColor clearColor].CGColor;
[self.view.layer addSublayer:layer1];
// 设置相同起点,相同控制点,终点不同时贝赛尔曲线比较(即,起点终点距离不同)-- 对比线(绿线)
UIBezierPath *path2 = [UIBezierPath bezierPath];
[path2 moveToPoint:CGPointMake(80, 80)];
[path2 addQuadCurveToPoint:CGPointMake(180, 120) controlPoint:CGPointMake(120, 40)];
CAShapeLayer *layer2 = [CAShapeLayer layer];
layer2.path = path2.CGPath;
layer2.strokeColor = [UIColor greenColor].CGColor;
layer2.fillColor = [UIColor clearColor].CGColor;
[self.view.layer addSublayer:layer2];
// 总结:起点和终点的距离越小,趋向控制点结束越早,趋向终点开始越早,曲线弧度越大。
// 起点终点相同,控制点不同 -- 对比线(蓝线)
UIBezierPath *path3 = [UIBezierPath bezierPath];
[path3 moveToPoint:CGPointMake(80, 80)];
[path3 addQuadCurveToPoint:CGPointMake(280, 120) controlPoint:CGPointMake(120, 20)];
CAShapeLayer *layer3 = [CAShapeLayer layer];
layer3.path = path3.CGPath;
layer3.strokeColor = [UIColor blueColor].CGColor;
layer3.fillColor = [UIColor clearColor].CGColor;
[self.view.layer addSublayer:layer3];
// 总结:控制点与起点和终点所在直线偏移距离越大,曲线弧度越大。
// 三次贝塞尔曲线 -- 紫线
UIBezierPath *path4 = [UIBezierPath bezierPath];
[path4 moveToPoint:CGPointMake(40, 200)];
[path4 addCurveToPoint:CGPointMake(280, 200) controlPoint1:CGPointMake(100, 160) controlPoint2:CGPointMake(200, 260)];
CAShapeLayer *layer4 = [CAShapeLayer layer];
layer4.path = path4.CGPath;
layer4.strokeColor = [UIColor purpleColor].CGColor;
layer4.fillColor = [UIColor clearColor].CGColor;
[self.view.layer addSublayer:layer4];