iOS通过CAShapeLayer和UIBezierPath画环形进度条

转其他博主文章

UIBezierPath可以绘制矢量路径,而CAShapeLayer是Layer的子类,可以在屏幕进行绘制,本文主要思想是:CAShapeLayer按照UIBezierPath的矢量路径进行绘制。

效果图如图:

iOS通过CAShapeLayer和UIBezierPath画环形进度条_第1张图片

方法如下:

[objc]view plaincopy

@interfaceViewController (){

CAShapeLayer*shapeLayer;

NSTimer*timer;

}

@end

@implementationViewController

- (void)viewDidLoad {

[superviewDidLoad];

//第一步,通过UIBezierPath设置圆形的矢量路径

UIBezierPath*circle = [UIBezierPathbezierPathWithOvalInRect:CGRectMake(0,0,200,200)];

//第二步,用CAShapeLayer沿着第一步的路径画一个完整的环(颜色灰色,起始点0,终结点1)

CAShapeLayer*bgLayer = [CAShapeLayerlayer];

bgLayer.frame= CGRectMake(0,0,200,200);//设置Frame

bgLayer.position=self.view.center;//居中显示

bgLayer.fillColor= [UIColorclearColor].CGColor;//填充颜色=透明色

bgLayer.lineWidth=2.f;//线条大小

bgLayer.strokeColor= [UIColorgrayColor].CGColor;//线条颜色

bgLayer.strokeStart=0.f;//路径开始位置

bgLayer.strokeEnd=1.f;//路径结束位置

bgLayer.path= circle.CGPath;//设置bgLayer的绘制路径为circle的路径

[self.view.layeraddSublayer:bgLayer];//添加到屏幕上

//第三步,用CAShapeLayer沿着第一步的路径画一个红色的环形进度条,但是起始点=终结点=0,所以开始不可见

shapeLayer = [CAShapeLayerlayer];

shapeLayer.frame= CGRectMake(0,0,200,200);

shapeLayer.position=self.view.center;

shapeLayer.fillColor= [UIColorclearColor].CGColor;

shapeLayer.lineWidth=2.f;

shapeLayer.strokeColor= [UIColorredColor].CGColor;

shapeLayer.strokeStart=0;

shapeLayer.strokeEnd=0;

shapeLayer.path= circle.CGPath;

[self.view.layeraddSublayer:shapeLayer];

//第四步,用一个定时器进行测试,每一秒,进度加10%

timer = [NSTimerscheduledTimerWithTimeInterval:1.ftarget:selfselector:@selector(animate)userInfo:nilrepeats:YES];

}

-(void)animate{

shapeLayer.strokeEnd+=0.1;

}

我们可以对以上代码封装为一个CircleView,继承自View,封装后代码如下:

CircleView.h文件

[objc]view plaincopy

#import 

@interfaceCircleView : UIView

@property(assign,nonatomic)CGFloat startValue;

@property(assign,nonatomic)CGFloat lineWidth;

@property(assign,nonatomic)CGFloat value;

@property(strong,nonatomic)UIColor*lineColr;

@end

CircleView.m文件

[objc]view plaincopy

#import "CircleView.h"

@interfaceCircleView()

@property(strong,nonatomic)UIBezierPath*path;

@property(strong,nonatomic)CAShapeLayer*shapeLayer;

@property(strong,nonatomic)CAShapeLayer*bgLayer;

@end

@implementationCircleView

- (instancetype)initWithFrame:(CGRect)frame

{

self= [superinitWithFrame:frame];

if(self) {

_path = [UIBezierPathbezierPathWithOvalInRect:self.bounds];

_bgLayer = [CAShapeLayerlayer];

_bgLayer.frame=self.bounds;

_bgLayer.fillColor= [UIColorclearColor].CGColor;

_bgLayer.lineWidth=2.f;

_bgLayer.strokeColor= [UIColorgrayColor].CGColor;

_bgLayer.strokeStart=0.f;

_bgLayer.strokeEnd=1.f;

_bgLayer.path= _path.CGPath;

[self.layeraddSublayer:_bgLayer];

_shapeLayer = [CAShapeLayerlayer];

_shapeLayer.frame=self.bounds;

_shapeLayer.fillColor= [UIColorclearColor].CGColor;

_shapeLayer.lineWidth=2.f;

_shapeLayer.lineCap= kCALineCapRound;

_shapeLayer.strokeColor= [UIColorredColor].CGColor;

_shapeLayer.strokeStart=0.f;

_shapeLayer.strokeEnd=0.f;

_shapeLayer.path= _path.CGPath;

[self.layeraddSublayer:_shapeLayer];

}

returnself;

}

@synthesizevalue = _value;

-(void)setValue:(CGFloat)value{

_value = value;

_shapeLayer.strokeEnd= value;

}

-(CGFloat)value{

return_value;

}

@synthesizelineColr = _lineColr;

-(void)setLineColr:(UIColor*)lineColr{

_lineColr = lineColr;

_shapeLayer.strokeColor= lineColr.CGColor;

}

-(UIColor*)lineColr{

return_lineColr;

}

@synthesizelineWidth = _lineWidth;

-(void)setLineWidth:(CGFloat)lineWidth{

_lineWidth = lineWidth;

_shapeLayer.lineWidth= lineWidth;

_bgLayer.lineWidth= lineWidth;

}

-(CGFloat)lineWidth{

return_lineWidth;

}

@end

在需要使用的ViewContrller中使用以下代码调用即可

[objc]view plaincopy

CircleView*view = [[CircleViewalloc]initWithFrame:CGRectMake(0,0,200,200)];

[self.viewaddSubview:view];

view.center=self.view.center;

[viewsetLineWidth:6.f];

[viewsetLineColr:[UIColorredColor]];

另外默认的坐标如下图(图来自http://justsee.iteye.com/blog/1972853)

iOS通过CAShapeLayer和UIBezierPath画环形进度条_第2张图片

有时候我们需要开始点在顶部,即(3/2)π 处,其中一个思路是将整个View逆时针旋转90度即可,在CircleView.m的initWithFrame中添加以下代码即可:

[objc]view plaincopy

CGAffineTransform transform = CGAffineTransformIdentity;

self.transform= CGAffineTransformRotate(transform, -M_PI /2);

你可能感兴趣的:(iOS通过CAShapeLayer和UIBezierPath画环形进度条)