Files
OrderScheduling/Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/ControlView/ZFSliderView.m
DDIsFriend 8d563860f1 update
2023-08-28 18:29:21 +08:00

427 lines
14 KiB
Objective-C

//
// ZFSliderView.m
// ZFPlayer
//
// Copyright (c) 2016年 任子丰 ( http://github.com/renzifeng )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import "ZFSliderView.h"
#import "UIView+ZFFrame.h"
/** 滑块的大小 */
static const CGFloat kSliderBtnWH = 19.0;
/** 进度的高度 */
static const CGFloat kProgressH = 1.0;
/** 拖动slider动画的时间*/
static const CGFloat kAnimate = 0.3;
@implementation ZFSliderButton
// 重写此方法将按钮的点击范围扩大
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
CGRect bounds = self.bounds;
// 扩大点击区域
bounds = CGRectInset(bounds, -20, -20);
// 若点击的点在新的bounds里面。就返回yes
return CGRectContainsPoint(bounds, point);
}
@end
@interface ZFSliderView ()
/** 进度背景 */
@property (nonatomic, strong) UIImageView *bgProgressView;
/** 缓存进度 */
@property (nonatomic, strong) UIImageView *bufferProgressView;
/** 滑动进度 */
@property (nonatomic, strong) UIImageView *sliderProgressView;
/** 滑块 */
@property (nonatomic, strong) ZFSliderButton *sliderBtn;
@property (nonatomic, strong) UIView *loadingBarView;
@property (nonatomic, assign) BOOL isLoading;
@property (nonatomic, strong) UITapGestureRecognizer *tapGesture;
@end
@implementation ZFSliderView
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
self.allowTapped = YES;
self.animate = YES;
[self addSubViews];
}
return self;
}
- (void)awakeFromNib {
[super awakeFromNib];
self.allowTapped = YES;
self.animate = YES;
[self addSubViews];
}
- (void)layoutSubviews {
[super layoutSubviews];
if (isnan(self.value) || isnan(self.bufferValue)) return;
CGFloat min_x = 0;
CGFloat min_y = 0;
CGFloat min_w = 0;
CGFloat min_h = 0;
CGFloat min_view_w = self.bounds.size.width;
CGFloat min_view_h = self.bounds.size.height;
min_x = 0;
min_w = min_view_w;
min_y = 0;
min_h = self.sliderHeight;
self.bgProgressView.frame = CGRectMake(min_x, min_y, min_w, min_h);
min_x = 0;
min_y = 0;
min_w = self.thumbSize.width;
min_h = self.thumbSize.height;
self.sliderBtn.frame = CGRectMake(min_x, min_y, min_w, min_h);
self.sliderBtn.zf_centerX = self.bgProgressView.zf_width * self.value;
min_x = 0;
min_y = 0;
if (self.sliderBtn.hidden) {
min_w = self.bgProgressView.zf_width * self.value;
} else {
min_w = self.sliderBtn.zf_centerX;
}
min_h = self.sliderHeight;
self.sliderProgressView.frame = CGRectMake(min_x, min_y, min_w, min_h);
min_x = 0;
min_y = 0;
min_w = self.bgProgressView.zf_width * self.bufferValue;
min_h = self.sliderHeight;
self.bufferProgressView.frame = CGRectMake(min_x, min_y, min_w, min_h);
min_w = 0.1;
min_h = self.sliderHeight;
min_x = (min_view_w - min_w)/2;
min_y = (min_view_h - min_h)/2;
self.loadingBarView.frame = CGRectMake(min_x, min_y, min_w, min_h);
self.bgProgressView.zf_centerY = min_view_h * 0.5;
self.bufferProgressView.zf_centerY = min_view_h * 0.5;
self.sliderProgressView.zf_centerY = min_view_h * 0.5;
self.sliderBtn.zf_centerY = min_view_h * 0.5;
}
/**
添加子视图
*/
- (void)addSubViews {
self.thumbSize = CGSizeMake(kSliderBtnWH, kSliderBtnWH);
self.sliderHeight = kProgressH;
self.backgroundColor = [UIColor clearColor];
[self addSubview:self.bgProgressView];
[self addSubview:self.bufferProgressView];
[self addSubview:self.sliderProgressView];
[self addSubview:self.sliderBtn];
[self addSubview:self.loadingBarView];
// 添加点击手势
self.tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapped:)];
[self addGestureRecognizer:self.tapGesture];
// 添加滑动手势
UIPanGestureRecognizer *sliderGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(sliderGesture:)];
[self addGestureRecognizer:sliderGesture];
}
#pragma mark - Setter
- (void)setMaximumTrackTintColor:(UIColor *)maximumTrackTintColor {
_maximumTrackTintColor = maximumTrackTintColor;
self.bgProgressView.backgroundColor = maximumTrackTintColor;
}
- (void)setMinimumTrackTintColor:(UIColor *)minimumTrackTintColor {
_minimumTrackTintColor = minimumTrackTintColor;
self.sliderProgressView.backgroundColor = minimumTrackTintColor;
}
- (void)setBufferTrackTintColor:(UIColor *)bufferTrackTintColor {
_bufferTrackTintColor = bufferTrackTintColor;
self.bufferProgressView.backgroundColor = bufferTrackTintColor;
}
- (void)setLoadingTintColor:(UIColor *)loadingTintColor {
_loadingTintColor = loadingTintColor;
self.loadingBarView.backgroundColor = loadingTintColor;
}
- (void)setMaximumTrackImage:(UIImage *)maximumTrackImage {
_maximumTrackImage = maximumTrackImage;
self.bgProgressView.image = maximumTrackImage;
self.maximumTrackTintColor = [UIColor clearColor];
}
- (void)setMinimumTrackImage:(UIImage *)minimumTrackImage {
_minimumTrackImage = minimumTrackImage;
self.sliderProgressView.image = minimumTrackImage;
self.minimumTrackTintColor = [UIColor clearColor];
}
- (void)setBufferTrackImage:(UIImage *)bufferTrackImage {
_bufferTrackImage = bufferTrackImage;
self.bufferProgressView.image = bufferTrackImage;
self.bufferTrackTintColor = [UIColor clearColor];
}
- (void)setBackgroundImage:(UIImage *)image forState:(UIControlState)state {
[self.sliderBtn setBackgroundImage:image forState:state];
}
- (void)setThumbImage:(UIImage *)image forState:(UIControlState)state {
[self.sliderBtn setImage:image forState:state];
}
- (void)setValue:(float)value {
if (isnan(value)) return;
value = MIN(1.0, value);
_value = value;
if (self.sliderBtn.hidden) {
self.sliderProgressView.zf_width = self.bgProgressView.zf_width * value;
} else {
self.sliderBtn.zf_centerX = self.bgProgressView.zf_width * value;
self.sliderProgressView.zf_width = self.sliderBtn.zf_centerX;
}
}
- (void)setBufferValue:(float)bufferValue {
if (isnan(bufferValue)) return;
bufferValue = MIN(1.0, bufferValue);
_bufferValue = bufferValue;
self.bufferProgressView.zf_width = self.bgProgressView.zf_width * bufferValue;
}
- (void)setAllowTapped:(BOOL)allowTapped {
_allowTapped = allowTapped;
if (!allowTapped) {
[self removeGestureRecognizer:self.tapGesture];
}
}
- (void)setSliderHeight:(CGFloat)sliderHeight {
if (isnan(sliderHeight)) return;
_sliderHeight = sliderHeight;
self.bgProgressView.zf_height = sliderHeight;
self.bufferProgressView.zf_height = sliderHeight;
self.sliderProgressView.zf_height = sliderHeight;
}
- (void)setSliderRadius:(CGFloat)sliderRadius {
if (isnan(sliderRadius)) return;
_sliderRadius = sliderRadius;
self.bgProgressView.layer.cornerRadius = sliderRadius;
self.bufferProgressView.layer.cornerRadius = sliderRadius;
self.sliderProgressView.layer.cornerRadius = sliderRadius;
self.bgProgressView.layer.masksToBounds = YES;
self.bufferProgressView.layer.masksToBounds = YES;
self.sliderProgressView.layer.masksToBounds = YES;
}
- (void)setIsHideSliderBlock:(BOOL)isHideSliderBlock {
_isHideSliderBlock = isHideSliderBlock;
// 隐藏滑块,滑杆不可点击
if (isHideSliderBlock) {
self.sliderBtn.hidden = YES;
self.bgProgressView.zf_left = 0;
self.bufferProgressView.zf_left = 0;
self.sliderProgressView.zf_left = 0;
self.allowTapped = NO;
}
}
/**
* Starts animation of the spinner.
*/
- (void)startAnimating {
if (self.isLoading) return;
self.isLoading = YES;
self.bufferProgressView.hidden = YES;
self.sliderProgressView.hidden = YES;
self.sliderBtn.hidden = YES;
self.loadingBarView.hidden = NO;
[self.loadingBarView.layer removeAllAnimations];
CAAnimationGroup *animationGroup = [[CAAnimationGroup alloc] init];
animationGroup.duration = 0.4;
animationGroup.beginTime = CACurrentMediaTime() + 0.4;
animationGroup.repeatCount = MAXFLOAT;
animationGroup.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
CABasicAnimation *scaleAnimation = [CABasicAnimation animation];
scaleAnimation.keyPath = @"transform.scale.x";
scaleAnimation.fromValue = @(1000.0f);
scaleAnimation.toValue = @(self.zf_width * 10);
CABasicAnimation *alphaAnimation = [CABasicAnimation animation];
alphaAnimation.keyPath = @"opacity";
alphaAnimation.fromValue = @(1.0f);
alphaAnimation.toValue = @(0.0f);
[animationGroup setAnimations:@[scaleAnimation, alphaAnimation]];
[self.loadingBarView.layer addAnimation:animationGroup forKey:@"loading"];
}
/**
* Stops animation of the spinnner.
*/
- (void)stopAnimating {
self.isLoading = NO;
self.bufferProgressView.hidden = NO;
self.sliderProgressView.hidden = NO;
self.sliderBtn.hidden = self.isHideSliderBlock;
self.loadingBarView.hidden = YES;
[self.loadingBarView.layer removeAllAnimations];
}
#pragma mark - User Action
- (void)sliderGesture:(UIGestureRecognizer *)gesture {
switch (gesture.state) {
case UIGestureRecognizerStateBegan: {
[self sliderBtnTouchBegin:self.sliderBtn];
}
break;
case UIGestureRecognizerStateChanged: {
[self sliderBtnDragMoving:self.sliderBtn point:[gesture locationInView:self.bgProgressView]];
}
break;
case UIGestureRecognizerStateEnded: {
[self sliderBtnTouchEnded:self.sliderBtn];
}
break;
default:
break;
}
}
- (void)sliderBtnTouchBegin:(UIButton *)btn {
if ([self.delegate respondsToSelector:@selector(sliderTouchBegan:)]) {
[self.delegate sliderTouchBegan:self.value];
}
if (self.animate) {
[UIView animateWithDuration:kAnimate animations:^{
btn.transform = CGAffineTransformMakeScale(1.2, 1.2);
}];
}
}
- (void)sliderBtnTouchEnded:(UIButton *)btn {
if ([self.delegate respondsToSelector:@selector(sliderTouchEnded:)]) {
[self.delegate sliderTouchEnded:self.value];
}
if (self.animate) {
[UIView animateWithDuration:kAnimate animations:^{
btn.transform = CGAffineTransformIdentity;
}];
}
}
- (void)sliderBtnDragMoving:(UIButton *)btn point:(CGPoint)touchPoint {
// 点击的位置
CGPoint point = touchPoint;
// 获取进度值 由于btn是从 0-(self.width - btn.width)
CGFloat value = (point.x - btn.zf_width * 0.5) / self.bgProgressView.zf_width;
// value的值需在0-1之间
value = value >= 1.0 ? 1.0 : value <= 0.0 ? 0.0 : value;
if (self.value == value) return;
self.isForward = self.value < value;
self.value = value;
if ([self.delegate respondsToSelector:@selector(sliderValueChanged:)]) {
[self.delegate sliderValueChanged:value];
}
}
- (void)tapped:(UITapGestureRecognizer *)tap {
CGPoint point = [tap locationInView:self.bgProgressView];
// 获取进度
CGFloat value = (point.x - self.sliderBtn.zf_width * 0.5) * 1.0 / self.bgProgressView.zf_width;
value = value >= 1.0 ? 1.0 : value <= 0 ? 0 : value;
self.value = value;
if ([self.delegate respondsToSelector:@selector(sliderTapped:)]) {
[self.delegate sliderTapped:value];
}
}
#pragma mark - getter
- (UIView *)bgProgressView {
if (!_bgProgressView) {
_bgProgressView = [UIImageView new];
_bgProgressView.backgroundColor = [UIColor grayColor];
_bgProgressView.contentMode = UIViewContentModeScaleAspectFill;
_bgProgressView.clipsToBounds = YES;
}
return _bgProgressView;
}
- (UIView *)bufferProgressView {
if (!_bufferProgressView) {
_bufferProgressView = [UIImageView new];
_bufferProgressView.backgroundColor = [UIColor whiteColor];
_bufferProgressView.contentMode = UIViewContentModeScaleAspectFill;
_bufferProgressView.clipsToBounds = YES;
}
return _bufferProgressView;
}
- (UIView *)sliderProgressView {
if (!_sliderProgressView) {
_sliderProgressView = [UIImageView new];
_sliderProgressView.backgroundColor = [UIColor redColor];
_sliderProgressView.contentMode = UIViewContentModeScaleAspectFill;
_sliderProgressView.clipsToBounds = YES;
}
return _sliderProgressView;
}
- (ZFSliderButton *)sliderBtn {
if (!_sliderBtn) {
_sliderBtn = [ZFSliderButton buttonWithType:UIButtonTypeCustom];
[_sliderBtn setAdjustsImageWhenHighlighted:NO];
}
return _sliderBtn;
}
- (UIView *)loadingBarView {
if (!_loadingBarView) {
_loadingBarView = [[UIView alloc] init];
_loadingBarView.backgroundColor = [UIColor whiteColor];
_loadingBarView.hidden = YES;
}
return _loadingBarView;
}
@end