CAShapeLayer和CAGradientLayer使用

本文介绍了一种使用Swift和Objective-C实现的弧形进度条绘制方法。通过CAShapeLayer和CAGradientLayer创建了一个带有渐变效果的动态进度条,并通过strokeEnd属性实现了进度更新的动画效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文链接:http://www.ganlvji.com/gradient_circle_progress/



下面这个方法就是产生这个弧形:


#define degreesToRadians(x) (M_PI*(x)/180.0) //把角度转换成PI的方式

#define  PROGREESS_WIDTH 80 //圆直径

#define PROGRESS_LINE_WIDTH 4 //弧线的宽度


- (CALayer *)generateLayer
{
    CGRect rect = CGRectMake(0, 0, 100, 100);

    CAShapeLayer *_progressLayer = [CAShapeLayer layer];
    _progressLayer.frame = rect;
    _progressLayer.fillColor =  [[UIColor clearColor] CGColor];
    _progressLayer.strokeColor  = [[UIColor redColor] CGColor];
    _progressLayer.lineCap = kCALineCapRound;
    _progressLayer.lineWidth = PROGRESS_LINE_WIDTH;
    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(40, 40) radius:(80 - 4)/2 startAngle:degreesToRadians(-210) endAngle:degreesToRadians(30) clockwise:YES];//上面说明过了用来构建圆形
    _progressLayer.path = [path CGPath];
    _progressLayer.strokeEnd = 0.9;
    
    CALayer *gradientLayer = [CALayer layer];
    gradientLayer.frame = rect;
    
    CAGradientLayer *gradientLayer1 =  [CAGradientLayer layer];
    gradientLayer1.frame = CGRectMake(0, 0, CGRectGetWidth(rect) / 2, CGRectGetHeight(rect));
    [gradientLayer1 setColors:[NSArray arrayWithObjects:(id)[[UIColor redColor] CGColor],(id)[[UIColor yellowColor] CGColor], nil]];
    [gradientLayer1 setLocations:@[@0.5,@0.9]];
    [gradientLayer1 setStartPoint:CGPointMake(0.5, 1)];
    [gradientLayer1 setEndPoint:CGPointMake(0.5, 0)];
    [gradientLayer addSublayer:gradientLayer1];
    
    CAGradientLayer *gradientLayer2 =  [CAGradientLayer layer];
    gradientLayer2.frame = CGRectMake(CGRectGetWidth(rect) / 2, 0, CGRectGetWidth(rect) / 2, CGRectGetHeight(rect));
    [gradientLayer2 setColors:[NSArray arrayWithObjects:(id)[[UIColor yellowColor] CGColor],(id)[[UIColor blueColor] CGColor], nil]];
    [gradientLayer2 setLocations:@[@0.1,@0.5]];
    [gradientLayer2 setStartPoint:CGPointMake(0.5, 0)];
    [gradientLayer2 setEndPoint:CGPointMake(0.5, 1)];
    [gradientLayer addSublayer:gradientLayer2];
    
    
    [gradientLayer setMask:_progressLayer]; //用progressLayer来截取渐变层
    
    CAShapeLayer *bgLayer = [CAShapeLayer layer];
    bgLayer.frame = CGRectMake(0, 0, 100, 100);;
    bgLayer.fillColor = [[UIColor clearColor] CGColor];
    bgLayer.strokeColor = [[UIColor blueColor] CGColor];
    bgLayer.opacity = 0.1f;
    bgLayer.lineCap = kCALineCapRound;
    bgLayer.lineWidth = PROGRESS_LINE_WIDTH;
    UIBezierPath *bgPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(40, 40) radius:(80 - 4)/2 startAngle:degreesToRadians(-210) endAngle:degreesToRadians(30) clockwise:YES];//上面说明过了用来构建圆形
    bgLayer.path = [bgPath CGPath];
    
    CALayer *layer = [CALayer layer];
    [layer addSublayer:bgLayer];
    [layer addSublayer:gradientLayer];
    
    return layer;
}

CAShapeLayer有一个strokeEnd的属性,这个属性是从0到1的浮点类型,正好可以用表达百分比,而且这个属性是animatable,可以动态的表示进度的变化。
如下代码所示:
-(void)setPercent:(NSInteger)percent animated:(BOOL)animated
{
    [CATransaction begin];
    [CATransaction setDisableActions:!animated];
    [CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]];
    [CATransaction setAnimationDuration:MAIN_SCREEN_ANIMATION_TIME];
    _progressLayer.strokeEnd = percent/100.0;
    [CATransaction commit];
    
    _percent = percent;
}

记录方便以后理解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值