效果 如下:
.h
#import
@interface PAAudioAnimationView : UIView
- (void)startAnimation;
- (void)stopAnimation;
- (void)setSoundsValue:(CGFloat)value;
@end
.m
#import "PAAudioAnimationView.h"
@interface PAAudioAnimationView()
@property (nonatomic, assign) CGFloat itemLineWidth;
@property (nonatomic, assign) CGFloat itemLineSeparate;
@property (nonatomic, strong) UIColor *itemColor;
@property (nonatomic, strong) UIColor *itemBackColor;
@property (nonatomic, strong) CADisplayLink *displayLink;
@property (nonatomic, assign) CGFloat soundsValue;
@end
@implementation PAAudioAnimationView
- (instancetype)init{
if (self = [super init]) {
_itemLineWidth = 3;
_itemLineSeparate = 4;
_soundsValue = 0;
_itemColor = [UIColor colorWithRed:255/255.0 green:96/255.0 blue:0/255.0 alpha:1/1.0];
_itemBackColor = [UIColor colorWithRed:230/255.0 green:230/255.0 blue:230/255.0 alpha:1/1.0];
}
return self;
}
- (void)setFrame:(CGRect)frame{
[super setFrame:frame];
[self setItems];
[self stopLayer];
}
- (void)setSoundsValue:(CGFloat)value{
_soundsValue = value;
}
- (void)setItems{
[self removeAllSubLayers];
CGFloat width = self.frame.size.width;
NSInteger numberItem = (width - self.itemLineWidth) / (_itemLineWidth + _itemLineSeparate);
CGFloat layer_w = _itemLineWidth;
CGFloat layer_x = _itemLineSeparate;
CGFloat layer_h = self.frame.size.height;
CGFloat layer_y = self.frame.size.height - layer_h;
CGFloat min_x = (width - 48 - 34 * 2) / 2;
CGFloat max_x = (width - (width - 48 - 34 * 2) / 2);
for (int i = 0; i < numberItem; i++) {
layer_x = _itemLineSeparate + (_itemLineSeparate + _itemLineWidth) * i;
if (layer_x > min_x && layer_x < max_x) {
continue;
}
layer_y = [self layer_y:i];
layer_h = [self layer_h:layer_y];
UIBezierPath *itemLinePath = [UIBezierPath bezierPath];
[itemLinePath moveToPoint:CGPointMake(0, layer_y)];
[itemLinePath addLineToPoint:CGPointMake(0, layer_y + layer_h)];
CAShapeLayer *itemline = [CAShapeLayer layer];
itemline.lineCap = kCALineCapButt;
itemline.lineJoin = kCALineJoinRound;
[itemline setLineWidth:layer_w * 2];
itemline.strokeColor = [self.itemColor CGColor];
itemline.path = [itemLinePath CGPath];
UIView *dynamicView = [[UIView alloc]initWithFrame:CGRectMake(layer_x, layer_y, layer_w, layer_h)];
dynamicView.backgroundColor = self.itemBackColor;
dynamicView.layer.masksToBounds = YES;
dynamicView.layer.cornerRadius = layer_w / 2;
dynamicView.tag = 111;
[dynamicView.layer addSublayer:itemline];
[self addSubview:dynamicView];
}
}
- (CGFloat)layer_y:(int)i{
CGFloat layer_y = 0;
if (i % 4 == 0) {
layer_y = (self.height - self.height * 2 / 4) / 2;
}else if (i % 4 == 1){
layer_y = (self.height - self.height * 3 / 4) / 2;
}else if (i % 4 == 2){
layer_y = 0;
}else{
layer_y = (self.height - self.height * 3 / 4) / 2;;
}
return layer_y;
}
- (CGFloat)layer_h:(CGFloat)layer_y{
return (self.height - layer_y * 2);
}
- (void)removeAllSubLayers{
for (UIView *view in self.subviews) {
[view removeFromSuperview];
}
}
- (void)updateItemLevel{
NSArray *subViews = self.subviews;
for (int i = 0; i < subViews.count; i++) {
UIView *subView = subViews[i];
if (subView.tag == 111) {
NSArray *layers = subView.layer.sublayers;
CAShapeLayer *lineItem = (CAShapeLayer*)layers.firstObject;
CGFloat height = arc4random() % (NSInteger)self.frame.size.height * 2;
height *= self.soundsValue;
CGFloat value = (1 - height * 1.0 / self.frame.size.height);
value = value < 0 ? 0 : value;
lineItem.strokeStart = value;
lineItem.strokeEnd = 1;
}
}
}
- (void)stopLayer{
NSArray *subViews = self.subviews;
for (int i = 0; i < subViews.count; i++) {
UIView *subView = subViews[i];
if (subView.tag == 111) {
NSArray *layers = subView.layer.sublayers;
CAShapeLayer *lineItem = (CAShapeLayer*)layers.firstObject;
lineItem.strokeStart = 1;
lineItem.strokeEnd = 1;
}
}
}
#pragma mark - displayLink 定时器 动画
- (CADisplayLink *)displayLink{
if (!_displayLink) {
_displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(start)];
}
return _displayLink;
}
- (void)start{
[self updateItemLevel];
}
- (void)startAnimation{
self.displayLink.frameInterval = 6;
[self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
}
- (void)stopAnimation{
if (self.displayLink) {
[self.displayLink invalidate];
self.displayLink = nil;
[self stopLayer];
}
}
@end