You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

325 lines
11 KiB

//
// CKAudioProgressView.m
// CKAudioProgress
//
// Created by guo on 2019/5/14.
// Copyright © 2019 guo. All rights reserved.
//
#import "CKAudioProgressView.h"
#import "CALayer+CKViewCategory.h"
@interface CKAudioProgressView()
@property (nonatomic, assign) BOOL isSliding;
@property (nonatomic, assign) NSInteger audioLength;
@property (nonatomic, strong) UIView *slideView;
@property (nonatomic, strong) UILabel *lb_time;
// 进度指示器
@property (nonatomic, strong) UILabel *lb_indicator;
@property (nonatomic, strong) CALayer *bgLayer;
@property (nonatomic, strong) CALayer *cachedLayer;
@property (nonatomic, strong) UIView *progressLineView;
@end
@implementation CKAudioProgressView
- (instancetype)initWithFrame:(CGRect)frame type:(CKAudioProgressType)progressType {
self = [super initWithFrame:frame];
if (self) {
[self initViews];
}
return self;
}
- (void)initViews {
[self.layer addSublayer:self.bgLayer];
[self.layer addSublayer:self.cachedLayer];
[self addSubview:self.progressLineView];
[self addSubview:self.lb_indicator];
[self addSubview:self.lb_time];
[self addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGesture:)]];
[self setNeedsLayout];
}
- (void)layoutSubviews
{
[super layoutSubviews];
CGFloat originY = (self.bounds.size.height-2)/2;
self.bgLayer.ckOriginY = originY;
self.bgLayer.ckWidth = self.frame.size.width;
self.cachedLayer.ckOriginY = originY;
self.progressLineView.ckOriginY = originY;
_lb_time.ckOriginY = (self.bounds.size.height-_lb_time.bounds.size.height)/2;
}
#pragma mark - Action
static CGFloat percent = 0.0;
- (void)timeLabelPanGesture:(UIPanGestureRecognizer *)gesture
{
UIGestureRecognizerState state = gesture.state;
if (UIGestureRecognizerStateBegan == state) {
_isSliding = YES;
percent = 0.0;
if (_delegate && [_delegate respondsToSelector:@selector(audioProgressTouchBegin)]) {
[_delegate audioProgressTouchBegin];
}
[UIView animateWithDuration:kAnimatedDurationFast animations:^{
self.lb_indicator.alpha = 1;
}];
} else if (UIGestureRecognizerStateChanged == state) {
CGPoint translation = [gesture translationInView:self];
CGPoint slideViewCenter = CGPointMake(gesture.view.center.x+ translation.x, gesture.view.center.y);
slideViewCenter.x = MAX(gesture.view.bounds.size.width/2, slideViewCenter.x);
slideViewCenter.x = MIN(self.bounds.size.width-gesture.view.bounds.size.width/2, slideViewCenter.x);
gesture.view.center = slideViewCenter;
[gesture setTranslation:CGPointZero inView:self];
_progressLineView.width = gesture.view.frame.origin.x;
CGFloat totalWith = self.bounds.size.width - _lb_time.bounds.size.width;
NSInteger audioProgress = gesture.view.frame.origin.x / totalWith * self.audioLength;
percent = gesture.view.frame.origin.x / totalWith;
[self setProgress:audioProgress total:self.audioLength];
self.lb_indicator.ckOriginY = _lb_time.origin.y - 45;
self.lb_indicator.ckCenterX = _lb_time.center.x;
} else if (UIGestureRecognizerStateEnded == state || UIGestureRecognizerStateCancelled == state) {
_isSliding = NO;
NSInteger audioProgress = gesture.view.frame.origin.x / (self.bounds.size.width - _lb_time.bounds.size.width) * self.audioLength;
[UIView animateWithDuration:kAnimatedDurationFast animations:^{
self.lb_indicator.alpha = 0;
}];
if (_delegate && [_delegate respondsToSelector:@selector(audioProgresstouchEndhCurrentTime:totalTime:)]) {
[_delegate audioProgresstouchEndhCurrentTime:audioProgress totalTime:self.audioLength];
}
}
}
- (void)tapGesture:(UITapGestureRecognizer *)gesture
{
CGPoint translation = [gesture locationInView:self];
NSInteger audioProgress = translation.x / self.bounds.size.width * self.audioLength;
[self setProgress:audioProgress total:self.audioLength];
if (_delegate && [_delegate respondsToSelector:@selector(audioProgresstouchEndhCurrentTime:totalTime:)]) {
[_delegate audioProgresstouchEndhCurrentTime:audioProgress totalTime:self.audioLength];
}
}
- (void)setProgress:(NSInteger)progress total:(NSInteger)total
{
NSString *title = @"";
if (total >= 3600) {
title = [NSString stringWithFormat:@"%@/%@", [TFUtilsHelper getHourTimeTransformationWithTotalTimeLenght:progress], [TFUtilsHelper getHourTimeTransformationWithTotalTimeLenght:total]];
} else {
title = [NSString stringWithFormat:@"%@/%@", [TFUtilsHelper getMinuteTimeTransformationWithTotalTimeLenght:progress], [TFUtilsHelper getMinuteTimeTransformationWithTotalTimeLenght:total]];
}
_lb_time.text = title;
if (self.lb_indicator.alpha > 0) {
self.lb_indicator.text = title;
}
}
- (void)updateProgress:(CGFloat)progress audioLength:(NSInteger)audioLength
{
if (isnan(percent) || isinf(percent)) {
percent = 0;
}
if (audioLength <= 0) {
_lb_time.text = @"00:00/00:00";
self.lb_indicator.text = @"00:00/00:00";
_lb_time.xtfei_x = 0;
_progressLineView.xtfei_width = 0;
return;
}
if (progress > 1) {
percent = 1;
} else if (progress < 0) {
percent = 0;
} else {
percent = progress;
}
if (!_isSliding) {
self.audioLength = audioLength;
[self setProgress:(NSInteger)(percent*audioLength) total:audioLength];
CGFloat totalWith = self.bounds.size.width-_lb_time.bounds.size.width;
CGFloat playedWidth = totalWith*percent;
_progressLineView.width = playedWidth;
_lb_time.ckCenterX = playedWidth+_lb_time.bounds.size.width/2;
}
}
- (void)updateCacheProgress:(CGFloat)progress
{
if (!isnan(progress)) {
self.cachedLayer.ckWidth = self.frame.size.width * progress;
}
}
#pragma mark - Getter & Setter
- (void)setCachedBgColor:(UIColor *)cachedBgColor {
if (cachedBgColor) {
_cachedBgColor = cachedBgColor;
self.cachedLayer.backgroundColor = cachedBgColor.CGColor;
}
}
- (void)setProgressBgColor:(UIColor *)progressBgColor {
if (progressBgColor) {
_progressBgColor = progressBgColor;
self.bgLayer.backgroundColor = progressBgColor.CGColor;
}
}
- (void)setCornerRadius:(CGFloat)cornerRadius {
_cornerRadius = cornerRadius;
self.cornerRadius = cornerRadius;
self.bgLayer.cornerRadius = cornerRadius;
self.cachedLayer.cornerRadius = cornerRadius;
self.progressLineView.layer.cornerRadius = cornerRadius;
}
- (void)setColors:(NSArray *)colors {
if (!_playedBgColor && colors) {
_colors = colors;
}
}
- (void)setPlayedBgColor:(UIColor *)playedBgColor {
if (!_colors && playedBgColor) {
_playedBgColor = playedBgColor;
self.progressLineView.backgroundColor = playedBgColor;
}
}
- (void)setSlideViewBounds:(CGRect)slideViewBounds {
if (slideViewBounds.size.width > 0) {
_slideViewBounds = slideViewBounds;
self.lb_time.bounds = slideViewBounds;
[self setNeedsLayout];
}
}
- (void)setTotalTimeLength:(NSInteger)totalTimeLength
{
_totalTimeLength = totalTimeLength;
if (totalTimeLength >= 0) {
NSString *title = @"";
if (totalTimeLength >= 3600) {
title = [NSString stringWithFormat:@"%@/%@", [TFUtilsHelper getHourTimeTransformationWithTotalTimeLenght:totalTimeLength], [TFUtilsHelper getHourTimeTransformationWithTotalTimeLenght:totalTimeLength]];
} else {
title = [NSString stringWithFormat:@"%@/%@", [TFUtilsHelper getMinuteTimeTransformationWithTotalTimeLenght:totalTimeLength], [TFUtilsHelper getMinuteTimeTransformationWithTotalTimeLenght:totalTimeLength]];
}
_lb_time.xtfei_width = [TFViewHelper getDynamicWidthWithLabelFont:[UIFont systemFontOfSize:10] labelHeight:20 labelText:title] + kHalfMargin;
_lb_indicator.xtfei_width = [TFViewHelper getDynamicWidthWithLabelFont:kFont12 labelHeight:30 labelText:title] + kHalfMargin;
}
}
- (CALayer *)bgLayer {
if (!_bgLayer) {
_bgLayer = [CALayer layer];
_bgLayer.backgroundColor = _progressBgColor ? _progressBgColor.CGColor : [UIColor colorWithRed:242/255.0 green:242/255.0 blue:242/255.0 alpha:1].CGColor;
_bgLayer.frame = CGRectMake(0, (self.bounds.size.height-2)/2, self.bounds.size.width, 2);
}
return _bgLayer;
}
- (CALayer *)cachedLayer {
if (!_cachedLayer) {
_cachedLayer = [CALayer layer];
_cachedLayer.backgroundColor = [UIColor colorWithRed:230/255.0 green:230/255.0 blue:230/255.0 alpha:1.0].CGColor;
_cachedLayer.frame = CGRectMake(0, (self.bounds.size.height-2)/2, 0, 2);
}
return _cachedLayer;
}
- (UIView *)progressLineView {
if (!_progressLineView) {
_progressLineView = [[UIView alloc] init];
_progressLineView.frame = CGRectMake(0, (self.bounds.size.height - 2 ) / 2, 0, 2);
}
return _progressLineView;
}
- (UIView *)slideView {
if (!_slideView) {
_slideView = [UIView new];
_slideView.frame = CGRectMake(-(24-24/2-12/2), 0, 24, 24);
CAShapeLayer *dotLayer = [CAShapeLayer layer];
dotLayer.fillColor = [UIColor whiteColor].CGColor;
dotLayer.frame = CGRectMake((24-12)/2, (24-12)/2, 12, 12);
dotLayer.cornerRadius = 6;
dotLayer.shadowColor = [UIColor colorWithRed:255/255.0 green:120/255.0 blue:2/255.0 alpha:1.0].CGColor;
dotLayer.shadowOffset = CGSizeMake(0,0);
dotLayer.shadowOpacity = 1;
dotLayer.shadowRadius = 10;
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:dotLayer.bounds];
dotLayer.path = path.CGPath;
[_slideView.layer addSublayer:dotLayer];
}
return _slideView;
}
- (UILabel *)lb_indicator
{
if (!_lb_indicator) {
_lb_indicator = [[UILabel alloc] init];
_lb_indicator.font = kFont12;
_lb_indicator.textAlignment = NSTextAlignmentCenter;
_lb_indicator.textColor = kWhiteColor;
_lb_indicator.frame = CGRectMake(0, 0, 92, 30);
_lb_indicator.alpha = 0;
_lb_indicator.layer.cornerRadius = 15;
_lb_indicator.layer.backgroundColor = kColorRGBA(0, 0, 0, 0.7).CGColor;
_lb_indicator.userInteractionEnabled = YES;
}
return _lb_indicator;
}
- (UILabel *)lb_time {
if (!_lb_time) {
_lb_time = [UILabel new];
_lb_time.font = [UIFont systemFontOfSize:10];
_lb_time.textAlignment = NSTextAlignmentCenter;
_lb_time.textColor = kGrayTextDeepColor;
_lb_time.frame = CGRectMake(0, 0, 72, 20);
_lb_time.layer.cornerRadius = 10;
_lb_time.layer.shadowColor = [UIColor colorWithRed:87/255.0 green:92/255.0 blue:111/255.0 alpha:0.5].CGColor;
_lb_time.layer.shadowOffset = CGSizeMake(0,0);
_lb_time.layer.shadowOpacity = 3;
_lb_time.layer.shadowRadius = 1;
_lb_time.layer.backgroundColor = kWhiteColor.CGColor;
_lb_time.userInteractionEnabled = YES;
[_lb_time addGestureRecognizer:[[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(timeLabelPanGesture:)]];
}
return _lb_time;
}
@end