利用CALayer動畫實現漸層進度條,calayer進度條
今天是第一次寫部落格,希望在今後的日子裡大家可以共同進步提高。閑話不多說了,首先看一下。
其實這個空間是比較簡單的調用CALayer動畫的空間,首先我們做一下簡單的分析。這個動畫的組成分為兩部分,第一部分為填充部分,即“strokeEnd”,另一部分則是填充顏色,即“stroke color”。有這兩個動畫組成了一個CALayer的組動畫。
實現原理大致明確我們來用代碼實現一下,我們先修改一下它的初始化方法:
-(instancetype)initWithFrameAndProsse:(CGRect)frame prosseInfo:(ProssenInfo)prosseInfo
{
self = [super initWithFrame:frame];
if(self)
{
_prossenInfo = prosseInfo;
[self setCAShapeLayer];
}
return self;
}
這裡面我將所需的一部分關於CAShapeLayer的參數寫成了一個結構體,方便使用和尋找,接下來我們初始化一下CAShapeLayer這個屬性:
-(void)setCAShapeLayer
{
_prosseShape = [CAShapeLayer layer];
_prosseShape.strokeColor = _prossenInfo.lineColor;
_prosseShape.lineWidth = _prossenInfo.width;
_prosseShape.strokeStart = 0;
_prosseShape.strokeEnd = 0;
_prosseShape.path = [self prossePath];
_prosseShape.lineJoin = kCALineJoinRound;
_prosseShape.lineCap = kCALineCapRound;
_prosseShape.beginTime =0.1f;
[self.layer addSublayer:_prosseShape];
}這裡我們需要注意
_prosseShape.lineJoin = kCALineJoinRound;
_prosseShape.lineCap = kCALineCapRound;這兩句話,如果不加上的話實現出來的進度條就不是圓角的。
我們改如何給路徑呢?
-(AnimationPoint)animationPoint
{
CGFloat startPoint_x = self.frame.size.width*(_prossenInfo.minLength<_prossenInfo.maxLength?_prossenInfo.minLength:_prossenInfo.maxLength);
CGFloat endPoint_x = self.frame.size.width*(_prossenInfo.minLength>_prossenInfo.maxLength?_prossenInfo.minLength:_prossenInfo.maxLength);
AnimationPoint point = AnimationPointMake\
(CGPointMake(startPoint_x, self.frame.size.height/2.f-_prossenInfo.width/2.f), \
CGPointMake(endPoint_x, self.frame.size.height/2.f-_prossenInfo.width/2.f));
return point;
}
-(CGMutablePathRef)prossePath
{
AnimationPoint point = [self animationPoint];
CGMutablePathRef pathRef=CGPathCreateMutable();
CGPathMoveToPoint(pathRef, NULL,point.startPoint.x, point.startPoint.y);
CGPathAddLineToPoint(pathRef, NULL, point.endPoint.x,point.endPoint.y);
CGPathCloseSubpath(pathRef);
return pathRef;
}
我們給定了這個Layer的起始填充部分,顏色,寬度以及路徑,接下來我們開始著手關於它的動畫。
-(void)starAnimation:(NSArray *)colorArray time:(NSTimeInterval)time
{
__block BOOL colors = NO;
__weak CAShapeLayer *shape = _prosseShape;
__block NSMutableArray *animationArray = [NSMutableArray array];
_aniTime = time;
[shape animateKey:@"strokeEnd"
fromValue:[NSNumber numberWithFloat:0.f]
toValue:[NSNumber numberWithFloat:0.5f]
customize:^BOOL(CABasicAnimation *animation) {
animation.duration = time;
if (colorArray != nil) {
colors = YES;
[animationArray addObject:animation];
[shape keyAnimation:@"strokeColor"
keyValues:colorArray
customize:^BOOL(CAKeyframeAnimation *animation) {
animation.duration = time;
animation.calculationMode = kCAAnimationPaced;
[animationArray addObject:animation];
return colors;
}];
[shape animationGroupWithDuration:time
animations:animationArray
customize:^(CAAnimationGroup *animation) {
}];
}
else
{
colors = NO;
animation.delegate = self;
}
return colors;
}];
}
因為我們要實現的事漸層顏色的動畫效果,所以我們需要給定兩個參數,一個是顏色數組,一個是進度時間。(當然在實際的下載過程中我們是不知道進度時間的,所以這裡本人封裝的控制項還不具備很好的完整性,但是我們可以通過修改 toValue:[NSNumber numberWithFloat:0.5f]這個函數參數來實現下載進度,本人會在下篇部落格之前修改完畢)。接下來我們實現一下關於動畫時間的計算,因為CALayer動畫本來是不支援動畫時間監聽的,所以這裡面我用了一個定時器。
-(void)animationDidStart:(CAAnimation *)anim
{
_animationTimer = [NSTimer scheduledTimerWithTimeInterval:AnimationTimer target:self selector:@selector(progressDidStart:) userInfo:nil repeats:YES];
}
-(void)progressDidStart:(NSTimer *)timer
{
if (_delegate &&[_delegate respondsToSelector:@selector(prosseToPoint:withDot:)]) {
animationProgress += 1/(_aniTime/AnimationTimer);
if (animationProgress >= 1.0) {
animationProgress = 1.0;
}
[_delegate prosseToPoint:CGPointZero withDot:animationProgress];
}
}
-(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
if (_delegate &&[_delegate respondsToSelector:@selector(prosseToPoint:withDot:)]) {
animationProgress += 1/(_aniTime/AnimationTimer);
if (animationProgress >= 1.0) {
animationProgress = 1.0;
}
[_delegate prosseToPoint:CGPointZero withDot:animationProgress];
}
animationProgress = 0;
[_animationTimer invalidate];
_animationTimer = nil;
}
這樣我們一個簡單的進度條控制項就寫好了,下面我們來調用一下:
_proView = [[XDProsseView alloc]initWithFrameAndProsse:CGRectMake(10, 320, self.view.bounds.size.width-20, 50) prosseInfo:ProssenInfoMake(5,1.f , 0.0, [UIColor blueColor].CGColor)];
_proView.delegate = self;
[self.view addSubview:_proView];
初始化這個進度條,
[_proView starAnimation:[NSArray arrayWithObjects:(id)[UIColor greenColor].CGColor,(id)[UIColor redColor].CGColor,(id)[UIColor blackColor].CGColor, nil] time:10.234f];
設定開始,時間,顏色等。
-(void)prosseToPoint:(CGPoint)point withDot:(double)dot
{
NSLog(@"監聽進度條進度%@ %ld",NSStringFromCGPoint(point),dot);
}
第一次寫部落格,如果有什麼不妥的地方,希望大家及時提出來,我一定會積極改正,謝謝!