
一、實作原理
原理很簡單:通過給Layer添加一個運動路徑,使Layer在這個路徑下一直重複運動即可;
二、代碼
//動畫名稱
static NSString *AnimationName = @"ESSEQAnimation";
@implementation PlayingLineView
{
//線寬度
float _lineWidth;
//線顔色
UIColor *_lineColor;
//線的集合
NSMutableArray *_layerArr;
//線的動畫
NSMutableArray *_animationArr;
}
//初始化震動調
-(instancetype)initWithFrame:(CGRect)frame lineWidth:(float)lineWidth lineColor:(UIColor*)lineColor
{
self = [super initWithFrame:frame];
if (self) {
_lineWidth = lineWidth;
_lineColor = lineColor;
_layerArr = [NSMutableArray new];
_animationArr = [NSMutableArray new];
[self buildLayout];
}
return self;
}
//每一個震動條的運動路徑
-(NSArray*)values
{
return @[@[@1.0, @0.5, @0.1, @0.4, @0.7, @0.9, @1.0],
@[@1.0, @0.8, @0.5, @0.1, @0.5, @0.7, @1.0],
@[@1.0, @0.7, @0.4, @0.4, @0.7, @0.9, @1.0]];
}
//随機運動的時長
-(NSArray*)durations
{
return @[@(0.9),@(1.0),@(0.9)];
}
//建立三個豎條
-(void)buildLayout
{
float margin = (self.bounds.size.width - 3*_lineWidth)/4;
float height = self.bounds.size.height;
NSArray* layerHeight = @[@(0.6*height),@(0.8*height),@(0.9*height)];
for (int i = 0; i < [self values].count; i++) {
//初始化layer
CAShapeLayer *layer = [[CAShapeLayer alloc] init];
layer.fillColor = [UIColor clearColor].CGColor;
layer.lineCap = kCALineCapRound;
layer.strokeColor = _lineColor.CGColor;
layer.frame = self.bounds;
layer.lineWidth = _lineWidth;
[self.layer addSublayer:layer];
[_layerArr addObject:layer];
//通過貝塞爾曲線設定layer的移動路徑
CGFloat pillarHeight = [layerHeight[i] floatValue];
CGFloat x = (i+1)*margin + i*_lineWidth;
CGPoint startPoint = CGPointMake(x, height);
CGPoint toPoint = CGPointMake(x, height - pillarHeight);
UIBezierPath * path = [UIBezierPath bezierPath];
[path moveToPoint:startPoint];
[path addLineToPoint:toPoint];
layer.path = path.CGPath;
//設定動畫
CAKeyframeAnimation * animation = [CAKeyframeAnimation animationWithKeyPath:@"strokeEnd"];
animation.values = [self values][i];
animation.duration = [[self durations][i] floatValue];
animation.repeatCount = HUGE_VAL;
animation.removedOnCompletion = false;//必須設為false否則會被銷毀掉
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
[layer addAnimation:animation forKey:AnimationName];
[_animationArr addObject:animation];
}
}
//暫停
-(void)pause
{
for (int i = 0; i<_layerArr.count; i++) {
CAShapeLayer *layer = _layerArr[i];
[layer removeAnimationForKey:AnimationName];
}
}
//開始
-(void)start
{
for (int i = 0; i<_layerArr.count; i++) {
CAShapeLayer *layer = _layerArr[i];
CAKeyframeAnimation *animation = _animationArr[i];
[layer addAnimation:animation forKey:AnimationName];
}
}
Demo下載下傳