CAShapeLayer
一、关于CAShapeLayer
1.CAShapeLayer 继承于 CALayer 属于CoreAnimation框架(通过GPU来渲染图形),所以 CAShapeLayer 相对于 CoreGraphics 框架(使用CPU绘制图形)下的DrawRect绘图方法更高效,节省内存。
2.CAShapeLayer 的使用需要为其设置 path,一般使用 UIBezierPath 或 CGMutablePathRef 为其提供path。如果绘制动态图形可以使用 CADisplayLink 来产生变化的path。
3.CAShapeLayer 的 path 是闭合封闭的,绘制时会对你提供的非闭合路径自动封闭。
4.CAShapeLayer 本身是没有形状,它更具提供的 path 去绘制形状。CALayer 初始化后则是矩形的。
二、使用示例
1.使用 UIBezierPath 提供 path 绘制静态图形
- (void)darwStaticShapeLayer{ //创建出CAShapeLayer self.shapeLayer = [CAShapeLayer layer]; self.shapeLayer.anchorPoint = self.view.center; //填充颜色为ClearColor self.shapeLayer.fillColor = [UIColor clearColor].CGColor; //设置线条的宽度和颜色 self.shapeLayer.lineWidth = 4.0f; self.shapeLayer.strokeColor = [UIColor redColor].CGColor; //绘制的起点和终点 range[0,1] self.shapeLayer.strokeStart = 0; self.shapeLayer.strokeEnd = 0.75; //创建出圆形贝塞尔曲线 UIBezierPath *circlePath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(100, 100, 150, 150)]; //设置CAShapeLayer的path self.shapeLayer.path = circlePath.CGPath; //显示 [self.view.layer addSublayer:self.shapeLayer]; }
/** * 添加 CAPropertyAnimation 动画 * 如:CABasicAnimation */ - (void)addStartAnimation{ CABasicAnimation *startAnimation = [CABasicAnimation animationWithKeyPath:@"strokeStart"]; startAnimation.duration = 1.0; startAnimation.fromValue = [NSNumber numberWithFloat:0.0f]; startAnimation.toValue = [NSNumber numberWithFloat:1.0f]; startAnimation.repeatCount = CGFLOAT_MAX; [self.shapeLayer addAnimation:startAnimation forKey:@"strokeStartAnimation"]; }
2.使用 CGMutablePathRef 提供 path 绘制水波动画
@property (nonatomic, strong) CAShapeLayer *shapeLayer; @property (nonatomic, strong) CADisplayLink *displaylink; @property (nonatomic, assign) CGFloat offsetX; - (void)darwWaveShapeLayer{ self.shapeLayer = [CAShapeLayer layer]; self.shapeLayer.fillColor = [UIColor redColor].CGColor; [self.view.layer addSublayer:self.shapeLayer]; //path控制 self.displaylink = [CADisplayLink displayLinkWithTarget:self selector:@selector(setCurrentWaveLayerPath)]; [self.displaylink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes]; } -(void)setCurrentWaveLayerPath{ CGFloat waveCycle = 2 * M_PI / self.view.bounds.size.width; //正弦周期 if (_offsetX < self.view.bounds.size.width) { _offsetX += 0.1;//波峰移动速度 } else { _offsetX = 0.0; } CGMutablePathRef path = CGPathCreateMutable(); CGFloat y = 300; CGPathMoveToPoint(path, nil, 0, y); for (float x = 0.0f; x <= self.view.bounds.size.width ; x++) { // 正弦波浪公式 y = 10 * sin(waveCycle * x + _offsetX) + 300; CGPathAddLineToPoint(path, nil, x, y); } CGPathAddLineToPoint(path, nil, self.view.bounds.size.width, 450); CGPathAddLineToPoint(path, nil, 0, 450); CGPathCloseSubpath(path); self.shapeLayer.path = path; //释放path CGPathRelease(path); }