本文介绍: 在整个进度条视图添加拖拽手势,根据手势所在的位置参数转换宽度比例,实现修改播放进度这里关键用到手势的这个接口 *- (CGPoint)locationInView:(nullable UIView)view; **计算手势进度 和占的宽度比例完整代码这里为了方便,将两个类放到同一个文件当.h.m………

效果图

请添加图片描述

实现原理

在整个进度条视图添加拖拽手势 UIPanGestureRecognizer
,根据locationInView接口获取手势所在的位置参数然后转换宽度比例,实现修改播放进度

核心代码

手势响应

这里关键用到了手势的这个接口 *– (CGPoint)locationInView:(nullable UIView)view; **

- (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)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];
    }
}

完整代码

这里为了方便,将两个类放到同一个文件
.h

//
//  TPVerticalVideoSliderView.h
//  ThePaperBase
//
//  Created by liubo on 2022/7/8.
//  Copyright © 2022 scar1900. All rights reserved.
//

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@protocol TPVerticalVideoSliderViewDelegate <NSObject>

@optional
// 滑块滑动开始
- (void)sliderTouchBegan:(float)value;
// 滑块滑动
- (void)sliderValueChanged:(float)value;
// 滑块滑动结束
- (void)sliderTouchEnded:(float)value;
// 滑杆点击
- (void)sliderTapped:(float)value;

@end

@interface TPVerticalVideoSliderButton : UIButton

@end


@interface TPVerticalVideoSliderView : UIView

@property (nonatomic, weak) id<TPVerticalVideoSliderViewDelegate> delegate;

/** 滑块 */
@property (nonatomic, strong, readonly) TPVerticalVideoSliderButton *sliderBtn;

/** 默认滑杆的颜色 */
@property (nonatomic, strong) UIColor *maximumTrackTintColor;

/** 滑杆进度颜色 */
@property (nonatomic, strong) UIColor *minimumTrackTintColor;

/** 滑杆进度 */
@property (nonatomic, assign) float value;

/** 缓存进度 */
@property (nonatomic, assign) float bufferValue;

/** 是否允许点击,默认是YES */
@property (nonatomic, assign) BOOL allowTapped;

/** 设置滑杆的高度 */
@property (nonatomic, assign) CGFloat sliderHeight;

/// 是否正在拖动
@property (nonatomic, assign) BOOL isdragging;

/// 向前还是向后拖动
@property (nonatomic, assign) BOOL isForward;

@property (nonatomic, assign) CGSize thumbSize;

@end

NS_ASSUME_NONNULL_END

.m

//
//  TPVerticalVideoSliderView.m
//  ThePaperBase
//
//  Created by liubo on 2022/7/8.
//  Copyright © 2022 scar1900. All rights reserved.
//

#import "TPVerticalVideoSliderView.h"
#import "UIView+ZFFrame.h"

/** 进度的高度 */
static const CGFloat kVProgressH = 2.0;

@implementation TPVerticalVideoSliderButton

// 重写方法按钮的点击范围扩大
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    CGRect bounds = self.bounds;
    // 扩大点击区域
    bounds = CGRectInset(bounds, -20, -20);
    // 若点击的点在新的bounds里面。就返回yes
    return CGRectContainsPoint(bounds, point);
}

@end

@interface TPVerticalVideoSliderView ()

/** 进度背景 */
@property (nonatomic, strong) UIImageView *bgProgressView;
/** 滑动进度 */
@property (nonatomic, strong) UIImageView *sliderProgressView;
/** 滑块 */
@property (nonatomic, strong) TPVerticalVideoSliderButton *sliderBtn;

@property (nonatomic, assign) BOOL isLoading;

@property (nonatomic, strong) UITapGestureRecognizer *tapGesture;

@end

@implementation TPVerticalVideoSliderView

- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        self.allowTapped = YES;
        [self addSubViews];
    }
    return self;
}

- (void)awakeFromNib {
    [super awakeFromNib];
    self.allowTapped = 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_h = self.bounds.size.height;
    
    min_x = 0;
    min_y = 0;
    min_w = self.thumbSize.width;
    min_h = self.thumbSize.height;
    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, CGRectGetHeight(self.sliderProgressView.frame));
       
    self.bgProgressView.zf_bottom    = min_view_h - 10 * rectScale();
    self.sliderProgressView.zf_bottom = min_view_h - 10 * rectScale();
    self.sliderBtn.zf_centerY = self.sliderProgressView.zf_centerY;
}

/**
 添加视图
 */
- (void)addSubViews {
    self.thumbSize = CGSizeMake(10, 20);
    self.sliderHeight = kVProgressH;
    self.backgroundColor = [UIColor clearColor];
    [self addSubview:self.bgProgressView];
    [self addSubview:self.sliderProgressView];
    [self addSubview:self.sliderBtn];
    
    // 添加点击手势
    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];
    self.backgroundColor = [UIColor clearColor];
}

- (void)showContentWithBeginDragging:(BOOL)dragging
{
    self.sliderBtn.hidden = NO;
    self.sliderProgressView.hidden = NO;
    self.bgProgressView.hidden = NO;
    CGFloat height = 2;
    CGFloat buttonWidth = 4;
    CGFloat buttonHeight = 4;
    UIColor *minimumTrackTintColor = self.minimumTrackTintColor;
    CGFloat cornerRadius = 2;
    if (dragging) {
        height = 10;;
        buttonWidth = 9;
        buttonHeight = 18;
        minimumTrackTintColor = [UIColor colorWithHexString:@"0xf0f0f0"];
        cornerRadius = 1;
    }
    [UIView animateWithDuration:0.1 animations:^{
        self.sliderProgressView.bounds = CGRectMake(0, 0, CGRectGetWidth(self.sliderProgressView.bounds), height);
        self.bgProgressView.bounds = CGRectMake(0, 0, CGRectGetWidth(self.bgProgressView.bounds), height);
        self.sliderBtn.bounds = CGRectMake(0, 0, buttonWidth, buttonHeight);
        self.sliderProgressView.backgroundColor = minimumTrackTintColor;
        self.sliderBtn.backgroundColor = minimumTrackTintColor;
        self.sliderBtn.layer.cornerRadius = cornerRadius;
    }];
}

#pragma mark - Setter

- (void)setMaximumTrackTintColor:(UIColor *)maximumTrackTintColor {
    _maximumTrackTintColor = maximumTrackTintColor;
    self.bgProgressView.backgroundColor = maximumTrackTintColor;
}

- (void)setMinimumTrackTintColor:(UIColor *)minimumTrackTintColor {
    _minimumTrackTintColor = minimumTrackTintColor;
    self.sliderProgressView.backgroundColor = minimumTrackTintColor;
    self.sliderBtn.backgroundColor = minimumTrackTintColor;
}


- (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;
}

- (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.sliderProgressView.zf_height = sliderHeight;
}

#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];
    }
    [self showContentWithBeginDragging:YES];
}

- (void)sliderBtnTouchEnded:(UIButton *)btn {
    if ([self.delegate respondsToSelector:@selector(sliderTouchEnded:)]) {
        [self.delegate sliderTouchEnded:self.value];
    }
    [self showContentWithBeginDragging:NO];
}

- (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.frame = CGRectMake(0, 0, ScreenWidth, 2);
        _bgProgressView.contentMode = UIViewContentModeScaleAspectFill;
        _bgProgressView.clipsToBounds = YES;
    }
    return _bgProgressView;
}

- (UIView *)sliderProgressView {
    if (!_sliderProgressView) {
        _sliderProgressView = [UIImageView new];
        _sliderProgressView.backgroundColor = [UIColor colorWithHexString:@"0x999999"];
        _sliderProgressView.contentMode = UIViewContentModeScaleAspectFill;
        _sliderProgressView.clipsToBounds = YES;
    }
    return _sliderProgressView;
}

- (TPVerticalVideoSliderButton *)sliderBtn {
    if (!_sliderBtn) {
        _sliderBtn = [TPVerticalVideoSliderButton buttonWithType:UIButtonTypeCustom];
        [_sliderBtn setAdjustsImageWhenHighlighted:NO];
        _sliderBtn.frame = CGRectMake(0, 0, 4, 4);
        _sliderBtn.layer.masksToBounds = YES;
        _sliderBtn.layer.cornerRadius = 2;
    }
    return _sliderBtn;
}

@end

原文地址:https://blog.csdn.net/LIUXIAOXIAOBO/article/details/125683852

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。

如若转载,请注明出处:http://www.7code.cn/show_9983.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注