
一、实现原理
原理很简单:通过给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下载