本文介绍: 在整个进度条视图上添加拖拽手势,根据手势所在的位置参数转换成宽度比例,实现修改播放进度这里关键用到了手势的这个接口 *- (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];
}
}
完整代码
//
// 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进行投诉反馈,一经查实,立即删除!
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。