进度条(ProgressBar)估计在每个App中都会使用到,再加上最近学习完了CoreAnimation框架,故而想自己实现一款进度条玩玩。
进度条其实就是绘制一条线的过程,重点就是怎么让绘制线的过程“动”起来,要想“动”就需要用到CoreAnimation框架了,用CoreAnimation实现动画的过程主要分3步:
- 创建动画Path、CALayer;
- 创建合适的CAAnimation;
- 把CAAnimation添加到想要动画的CALayer上。
下面就依照这3个步骤逐步实现我们的进度条。
创建动画Path、CALayer
iOS中画路径最简单的就是用UIBezierPath实现(本文只需要画一条线),因为要实现进度条所以layer最好选用CAShapeLayer(因为CAShapeLayer有个strokeStart和strokeEnd属性非常方便用作进度条动画),再者进度条需要有前景色和背景色所以需要创建2个CAShapeLayer,相关伪代码如下:
@implementation NFPProgressView
{
//Layer
CAShapeLayer *progressLayer;
//backgroundLayer
CAShapeLayer *backgroundLayer;
UIBezierPath *progressPath;
}
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if(self)
{
//Path
progressPath = [UIBezierPath bezierPath];
[progressPath moveToPoint:CGPointMake(PROGRESSHEIGHT/2,frame.size.height/2)];
[progressPath addLineToPoint:CGPointMake(frame.size.width-PROGRESSHEIGHT/2,frame.size.height/2)];
//Layer
progressLayer = [CAShapeLayer layer];
progressLayer.path = progressPath.CGPath;
progressLayer.lineWidth = PROGRESSHEIGHT;
progressLayer.lineCap = kCALineCapRound;
progressLayer.strokeColor = [UIColor redColor].CGColor;
backgroundLayer = [CAShapeLayer layer];
backgroundLayer.path = progressPath.CGPath;
backgroundLayer.strokeColor = [UIColor greenColor].CGColor;
backgroundLayer.lineWidth = PROGRESSHEIGHT;
backgroundLayer.lineCap = kCALineCapRound;
[self.layer addSublayer:backgroundLayer];
[self.layer addSublayer:progressLayer];
self.progress = 0.0;
}
return self;
}
创建合适的CAAnimation
因进度条动画只有2帧(start、end)所以选用CABasicAnimation,创建时KeyPath设置为“strokeEnd”,创建动画的animationWithKeyPath:方法其本质上是KVO,也就是它会监听KeyPath的变化。至于KeyPath可以设置为哪些属性,CALayer中那些描述为Animatable的属性均可以(当然我们还可以自定义,但需要实现一系列的方法,needsDisplayForKey:、display之类的),比如path、lineWidth。以下是创建CAAnimation的伪代码:
CABasicAnimation *progressAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
progressAnimation.duration = 0.5f;
把CAAnimation添加到想要动画的CALayer上
这一步非常简单,只需把之前创建好的CAAnimation添加到之前创建好的CALayer上即可,伪代码如下:
[progressLayer addAnimation:progressAnimation forKey:@"progress"];
扫尾工作
到这一步时进度条主要的功能就已实现了,就剩下进度条前景色、背景色的设置这类属性的设置了,关于这些属性的设置只需要重写setter方法即可,伪代码如下:
@interface NFPProgressView : UIView
@property(nonatomic,strong) UIColor tintColor;
@property(nonatomic,strong) UIColor trackColor;
@end
@implementation NFPProgressView
- (void)setTintColor:(UIColor *)tintColor
{
progressLayer.strokeColor = tintColor.CGColor;
}
- (void)setTrackColor:(UIColor *)trackColor
{
backgroundLayer.strokeColor = trackColor.CGColor;
}
@end
Demo效果
本文完整代码github地址NFPProgressView
最终的Demo效果如下:
