标哥的技术博客:CALayer精讲
KenshinCui'Blog:CALayer And Core Animation
文顶顶博客: Quartz 2D
基本概念:
一、UIBezierPath
(1)介绍: UIBezierPath
是CGPathRef
数据类型的封装。使用此类可以定义简单的形状,如椭圆、矩形或者有多个直线和曲线段组成的形状等。使用UIBezierPath
可以创建基于矢量的路径,此类是Core Graphics
框架关于路径的封装。
(2)使用UIBezierPath
画图步骤:
- 创建一个
UIBezierPath
对象 - 调用
-moveToPoint:
设置初始线段的起点 - 添加线或者曲线去定义一个或者多个子路径
- 改变
UIBezierPath
对象跟绘图相关的属性。如,我们可以设置画笔的属性、填充样式等
(3)提供的绘图类方法:
+ (instancetype)bezierPath; //画矩形 + (instancetype)bezierPathWithRect:(CGRect)rect; //画内切圆(或椭圆) + (instancetype)bezierPathWithOvalInRect:(CGRect)rect; //画带圆角的矩形 + (instancetype)bezierPathWithRoundedRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius; /*画带部门圆角的矩形 * rect弧线所处的矩形区域 * UIRectCorner 指定哪个角为圆角 * cornerRadii 圆角弧的大小
*/ + (instancetype)bezierPathWithRoundedRect:(CGRect)rect byRoundingCorners:(UIRectCorner)corners cornerRadii:(CGSize)cornerRadii; /*画弧线 * center: 弧线中心点的坐标 * radius: 弧线所在圆的半径 * startAngle: 弧线开始的弧度 * endAngle: 弧线结束的弧度 * clockwise: 是否顺时针画弧线 */ + (instancetype)bezierPathWithArcCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise; + (instancetype)bezierPathWithCGPath:(CGPathRef)CGPath;
(4)画弧线
角度和弧度的转换
1、弧度转角度 #define RADIANS_TO_DEGREES(radians) ((radians) * (180.0 / M_PI))
2、角度转弧度 #define DEGREES_TO_RADIANS(angle) ((angle) / 180.0 * M_PI)
2、角度转弧度 #define DEGREES_TO_RADIANS(angle) ((angle) / 180.0 * M_PI)
(5)画二次贝塞尔曲线
//方法 - (void)addQuadCurveToPoint:(CGPoint)endPoint controlPoint:(CGPoint)controlPoint
eg:
UIBezierPath *path = [UIBezierPath bezierPath]; // 首先设置一个起始点 [path moveToPoint:CGPointMake(20, self.frame.size.height - 100)]; // 添加二次曲线 [path addQuadCurveToPoint:CGPointMake(self.frame.size.width - 20, self.frame.size.height - 100) controlPoint:CGPointMake(self.frame.size.width / 2, 0)]; //曲线属性设置 path.lineCapStyle = kCGLineCapRound; path.lineJoinStyle = kCGLineJoinRound; path.lineWidth = 1.0; UIColor *strokeColor = [UIColor redColor]; [strokeColor set]; [path stroke];
(6)画三次贝塞尔曲线
贝塞尔曲线必定通过首尾两个点,称为端点;中间两个点虽然未必要通过,但却起到牵制曲线形状路径的作用,称作控制点。关于三次贝塞尔曲线的控制器,看下图:
//设置起点 - moveToPoint:(CGPoint)startPoint //两个控制点 - (void)addCurveToPoint:(CGPoint)endPoint controlPoint1:(CGPoint)controlPoint1 controlPoint2:(CGPoint)controlPoint2
(二)CAShapeLayer
它有一个path
属性,而UIBezierPath
就是对CGPathRef
类型的封装,因此这两者配合起来使用
@property(nullable) CGPathRef path;
CAShapeLayer与UIBezierPath的关系:
1、CAShapeLayer中shape代表形状的意思,所以需要形状才能生效
2、贝塞尔曲线可以创建基于矢量的路径,而UIBezierPath类是对CGPathRef的封装
3、贝塞尔曲线给CAShapeLayer提供路径,CAShapeLayer在提供的路径中进行渲染。路径会闭环,所以绘制出了Shape
4、用于CAShapeLayer的贝塞尔曲线作为path,其path是一个首尾相接的闭环的曲线,即使该贝塞尔曲线不是一个闭环的曲线
CAShapeLayer和drawRect的比较
1、drawRect:属于CoreGraphics框架,占用CPU,性能消耗大
2、CAShapeLayer:属于CoreAnimation框架,通过GPU来渲染图形,节省性能。动画渲染直接提交给手机GPU,不消耗内存