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);
}

 

posted @ 2016-07-05 11:29  moyazi  阅读(512)  评论(0编辑  收藏  举报