ios -- 为导航栏添加播放动画

FLAudioVisualizerView.h

#import <UIKit/UIKit.h>

@interface FLAudioVisualizerView : UIView

#pragma mark -

// 默认UIEdgeInsetsZero
@property (nonatomic, assign) UIEdgeInsets contentInsets;
// 默认为4
@property (nonatomic, assign) NSInteger barCount;
@property (nonatomic, copy) NSArray<NSNumber *> *barHeightRateList;
// 默认白色
@property (nonatomic, copy) UIColor *barColor;
// 默认2
@property (nonatomic, assign) CGFloat cornerRadius;
// 默认5
@property (nonatomic, assign) CGFloat barSpace;
// NSValue包装CGPoint
@property (nonatomic, strong) NSArray<NSValue *> *aniamteOffsetList;
@property (nonatomic, readonly) BOOL isAniamting;

- (void)restart;
- (void)start;
- (void)stop;

@end

 

FLAudioVisualizerView.m

#import "FLAudioVisualizerView.h"

@interface FLAudioVisualizerView ()

@property (nonatomic, strong) NSArray<UIView *> *barList;
@property (nonatomic, assign) BOOL isAniamting;

@end

@implementation FLAudioVisualizerView

#pragma mark -

- (id)initWithFrame:(CGRect)frame
{
    if (self = [super initWithFrame:frame]) {
        [self setBarCount:4];
        _barSpace = 5;
        _barColor = [UIColor whiteColor];
        self.cornerRadius = 2;
        self.barHeightRateList = @[@(0.4), @(0.75), @(0.55), @(0.95)];
        self.transform = CGAffineTransformMakeRotation(M_PI);
        self.aniamteOffsetList = @[[NSValue valueWithCGPoint:CGPointMake(0.1, 0.4)],
                                   [NSValue valueWithCGPoint:CGPointMake(0.75, 0.3)],
                                   [NSValue valueWithCGPoint:CGPointMake(0.2, 0.55)],
                                   [NSValue valueWithCGPoint:CGPointMake(0.94, 0.4)],
                                   ];
        self.contentInsets = UIEdgeInsetsZero;
    }
    return self;
}

- (void)layoutSubviews
{
    [super layoutSubviews];
    CGRect rect = self.bounds;
    if (fabs(rect.size.width) < 1e-3 || fabs(rect.size.height) < 1e-3 || rect.size.width < 0 || rect.size.height < 0 ) {
        return;
    }
    rect = CGRectWithEdgeInserts(rect, self.contentInsets);
    __block CGRect barRect = rect;
    barRect.size.width = (rect.size.width - (self.barCount - 1) * self.barSpace) / self.barCount;
    NSArray<NSNumber *> *barHeightRateList = self.barHeightRateList.reverseObjectEnumerator.allObjects;
    [self.barList enumerateObjectsUsingBlock:^(UIView * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        obj.layer.anchorPoint = CGPointZero;
        CGFloat rate = 1.0;
        if (idx < barHeightRateList.count) rate = barHeightRateList[idx].floatValue;
        barRect.size.height = rect.size.height * rate;
        obj.frame = barRect;
        barRect.origin.x += barRect.size.width + self.barSpace;
    }];
}

#pragma mark -

static CGRect CGRectWithEdgeInserts(CGRect rect, UIEdgeInsets inserts)
{
    rect.origin.x += inserts.left;
    rect.origin.y += inserts.top;
    rect.size.width -= inserts.left + inserts.right;
    rect.size.height -= inserts.top + inserts.bottom;
    return rect;
}

#pragma mark -

- (void)setBarCount:(NSInteger)barCount
{
    _barCount = barCount;
    NSInteger diff = self.barList.count - barCount;
    if (diff > 0) {
        NSArray<UIView *> *removeBarViewList = [self.barList subarrayWithRange:NSMakeRange(barCount, diff)];
        [removeBarViewList makeObjectsPerformSelector:@selector(removeFromSuperview)];
        self.barList = [self.barList subarrayWithRange:NSMakeRange(0, barCount)];
    } else if (diff < 0) {
        diff = -diff;
        NSMutableArray *addBarViewList = [NSMutableArray arrayWithCapacity:diff];
        for (NSInteger index = 0; index < diff; index ++) {
            UIView *imageView = [[UIView alloc] init];
            imageView.clipsToBounds = YES;
            imageView.layer.cornerRadius = self.cornerRadius;
            [addBarViewList addObject:imageView];
            imageView.backgroundColor = [UIColor whiteColor];
        }
        if (self.barList) {
            self.barList = [self.barList arrayByAddingObjectsFromArray:addBarViewList];
        } else {
            self.barList = addBarViewList;
        }
    }
    [self.barList enumerateObjectsUsingBlock:^(UIView * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        [self addSubview:obj];
    }];
}

- (void)setCornerRadius:(CGFloat)cornerRadius
{
    _cornerRadius = cornerRadius;
    [self.barList enumerateObjectsUsingBlock:^(UIView * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        obj.layer.cornerRadius = cornerRadius;
    }];
}

- (void)setBarColor:(UIColor *)barColor
{
    [self.barList enumerateObjectsUsingBlock:^(UIView * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        obj.backgroundColor = barColor;
    }];
}

- (void)aniamteWithBar:(UIView *)bar startHeight:(CGFloat)startHeight endHeight:(CGFloat)endHeight
{
    CABasicAnimation * animation;
    animation = [CABasicAnimation animationWithKeyPath:@"bounds.size.height"];
    animation.fromValue = [NSNumber numberWithFloat:startHeight];
    animation.toValue = [NSNumber numberWithFloat:endHeight];
    animation.duration = 0.25;
    animation.repeatCount = MAXFLOAT;
    animation.autoreverses = YES;
    [bar.layer addAnimation:animation forKey:@"bounds.size.height"];
}

- (void)restart
{
    [self stop];
    [self start];
}

- (void)start
{
    if (self.isAniamting) return;
    self.isAniamting = YES;
    NSArray<NSValue *> *aniamteOffsetList = self.aniamteOffsetList.reverseObjectEnumerator.allObjects;
    [self.barList enumerateObjectsUsingBlock:^(UIView * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        if (idx < aniamteOffsetList.count) {
            CGRect rect = CGRectWithEdgeInserts(self.bounds, self.contentInsets);
            CGPoint offset = aniamteOffsetList[idx].CGPointValue;
            [self aniamteWithBar:obj startHeight:rect.size.height * offset.x endHeight:rect.size.height * offset.y];
        }
    }];
}

- (void)stop
{
    self.isAniamting = NO;
    [self.barList enumerateObjectsUsingBlock:^(UIView * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        [obj.layer removeAllAnimations];
    }];
}

@end

 

 

ViewController.m

#import "ViewController.h"
#import "FLAudioVisualizerView.h"

#define kScreen_width [UIScreen mainScreen].bounds.size.width
#define SCREEN_HEIGHT [UIScreen mainScreen].bounds.size.height

@interface ViewController ()

@property (nonatomic, strong) FLAudioVisualizerView *visualizerView;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
    
    self.title = @"首页";
    //修改导航栏标题字体大小和颜色,背景颜色
    [self.navigationController.navigationBar setBarTintColor:[UIColor whiteColor]];
    [self.navigationController.navigationBar setTitleTextAttributes:@{
                                                                      NSFontAttributeName:[UIFont systemFontOfSize:17],NSForegroundColorAttributeName:[UIColor blackColor]
                                                                      }];
    UIButton *playBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    playBtn.frame = CGRectMake(10, 100, 100, 20);
    [self.view addSubview:playBtn];
    [playBtn setTitle:@"开始播放" forState:UIControlStateNormal];
    [playBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    [playBtn addTarget:self action:@selector(playClick) forControlEvents:UIControlEventTouchUpInside];
    
    UIButton *stopPlayBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    stopPlayBtn.frame = CGRectMake(10, 150, 100, 20);
    [self.view addSubview:stopPlayBtn];
    [stopPlayBtn setTitle:@"停止播放" forState:UIControlStateNormal];
    [stopPlayBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    [stopPlayBtn addTarget:self action:@selector(stopPlayBtnClick) forControlEvents:UIControlEventTouchUpInside];
    [self setupVisualizerView];
}

- (void)setupVisualizerView
{
    CGSize size = CGSizeMake(23, 22);
    UIEdgeInsets insets = UIEdgeInsetsMake(10, 0, 10, 20);
    size.width += insets.left + insets.right;
    size.height += insets.top + insets.bottom;
    // 直接直接使用visualizerView的时候,在侧滑返回的时候,会出现很奇怪的现象,visualizerView的frame会发生变化,导致显示异常
    UIView *containerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, size.width, size.height)];
    FLAudioVisualizerView *visualizerView = [[FLAudioVisualizerView alloc] initWithFrame:CGRectMake(0, 0, size.width, size.height)];
    self.visualizerView = visualizerView;
    [containerView addSubview:visualizerView];
    visualizerView.barColor = [UIColor colorWithRed:63/255 green:63/255 blue:64/255 alpha:1];
    visualizerView.contentInsets = insets;
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(gotoCurrentPlayPage)];
    [containerView addGestureRecognizer:tap];
    UIBarButtonItem *barItem = [[UIBarButtonItem alloc] initWithCustomView:containerView];
    self.navigationItem.rightBarButtonItem = barItem;
    
    
    
    
}

- (void)gotoCurrentPlayPage
{
    NSLog(@"点击了播放按钮");
}

- (void)playClick
{
    NSLog(@"1");
    [self.visualizerView restart];
}

- (void)stopPlayBtnClick
{
    NSLog(@"2");
    [self.visualizerView stop];
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


@end

 

posted on 2017-10-11 10:29  麦芽呀~  阅读(307)  评论(0编辑  收藏  举报