自定义UISlider

iOS系统提供的UISlider已经能满足很多需求,如果不行在继承于UISlider自定义稍微自定义一下,功能很全。包括添加点击事件,设置“播放点”等这些功能都可通过继承自定义实现。

以下是继承UISlider实现的半个自定义的点播slider

  • 设置进度条高度
  • slider添加progress
  • slider点击

slider实现

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@class PlayerSlider;

@protocol PlayerSliderDelegate <NSObject>

- (void)sliderTouchBegan:(PlayerSlider *)slider;
- (void)sliderValueChanged:(PlayerSlider *)slider;
- (void)sliderTouchEnded:(PlayerSlider *)slider;

- (void)sliderSignleTouch:(PlayerSlider *)slider;

@end


@interface PlayerSlider : UISlider

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

@property (nonatomic, assign) BOOL isDragging;

@property (nonatomic, strong) UIProgressView *progressView;

@end

NS_ASSUME_NONNULL_END
#import "PlayerSlider.h"

@interface PlayerSlider ()

@property (nonatomic, strong) UITapGestureRecognizer *sliderTap;

@end


@implementation PlayerSlider

- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        [self addInitUI];
        [self addSliderTarget];
        [self sliderDefaultSet];
    }
    return self;
}
- (instancetype)init {
    if (self = [super init]) {
        [self addInitUI];
        [self addSliderTarget];
        [self sliderDefaultSet];
    }
    return self;
}

- (void)layoutSubviews {
    [super layoutSubviews];
    
    //坐标x 预留出滑块的宽度
    _progressView.frame = CGRectMake(20, CGRectGetHeight(self.frame)*0.5-1, CGRectGetWidth(self.frame)-20, 2);
}

//设置进度条高度为2
- (CGRect)trackRectForBounds:(CGRect)bounds
{
    CGRect suBounds = [super trackRectForBounds:bounds];
    return CGRectMake(suBounds.origin.x, suBounds.origin.y, suBounds.size.width, 2);
}
//设置滑块可触摸范围大小
- (CGRect)thumbRectForBounds:(CGRect)bounds trackRect:(CGRect)rect value:(float)value
{
    CGRect suBounds = [super thumbRectForBounds:bounds trackRect:rect value:value];
    return CGRectMake(suBounds.origin.x, suBounds.origin.y-10, suBounds.size.width+20, suBounds.size.height+20);
}

- (void)addInitUI {
    _progressView                   = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault];
    _progressView.progressTintColor = [UIColor colorWithRed:1 green:1 blue:1 alpha:0.6];
    _progressView.trackTintColor    = [UIColor clearColor];
    _progressView.layer.masksToBounds = YES;
    _progressView.layer.cornerRadius  = 1;
    _progressView.progress = 0;
    [self addSubview:_progressView];
    [self sendSubviewToBack:_progressView];
}

- (void)addSliderTarget {
    // slider开始滑动事件
    [self addTarget:self action:@selector(progressSliderTouchBegan:) forControlEvents:UIControlEventTouchDown];
    // slider滑动中事件
    [self addTarget:self action:@selector(progressSliderValueChanged:) forControlEvents:UIControlEventValueChanged];
    // slider结束滑动事件
    [self addTarget:self action:@selector(progressSliderTouchEnded:) forControlEvents:UIControlEventTouchUpInside | UIControlEventTouchUpOutside];
    // slider点击事件
    self.sliderTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(sliderTapAction:)];
    [self addGestureRecognizer:self.sliderTap];
}
- (void)sliderDefaultSet {
    [self setMinimumTrackTintColor:[UIColor colorWithRed:0/255.0 green:122/255.0 blue:255/255.0 alpha:1.0]];
    [self setMaximumTrackTintColor:[UIColor colorWithRed:255/255.0 green:255/255.0 blue:255/255.0 alpha:0.5]];
    [self setThumbImage:[UIImage imageNamed:@"SKinBundle.bundle/seekbar"] forState:UIControlStateNormal];
}

- (void)progressSliderTouchBegan:(UISlider *)sender {
    self.sliderTap.enabled = NO;
    self.isDragging = YES;
    if ([self.delegate respondsToSelector:@selector(sliderTouchBegan:)]) {
        [self.delegate sliderTouchBegan:self];
    }
}
- (void)progressSliderValueChanged:(UISlider *)sender {
    if ([self.delegate respondsToSelector:@selector(sliderValueChanged:)]) {
        [self.delegate sliderValueChanged:self];
    }
}
- (void)progressSliderTouchEnded:(UISlider *)sender {
    if ([self.delegate respondsToSelector:@selector(sliderTouchEnded:)]) {
        [self.delegate sliderTouchEnded:self];
    }
    self.sliderTap.enabled = YES;
    self.isDragging = NO;
}

- (void)sliderTapAction:(UITapGestureRecognizer *)tap
{
    self.isDragging = YES;
    
    CGPoint point = [tap locationInView:self];
    CGFloat value = (self.maximumValue - self.minimumValue) * (point.x / self.frame.size.width );
    [self setValue:value animated:YES];


    if ([self.delegate respondsToSelector:@selector(sliderSignleTouch:)]) {
        [self.delegate sliderSignleTouch:self];
    }
    
    self.isDragging = NO;
}

@end
+ (NSString *)timeFormat:(NSInteger)totalTime {
    if (totalTime < 0) {
        return @"00:00";
    }
    NSInteger durHour = totalTime / 3600;
    NSInteger durMin = (totalTime / 60) % 60;
    NSInteger durSec = totalTime % 60;
    
    if (durHour > 0) {
        return [NSString stringWithFormat:@"%zd:%02zd:%02zd", durHour, durMin, durSec];
    } else {
        return [NSString stringWithFormat:@"%02zd:%02zd", durMin, durSec];
    }
}

slider设置

将点播播放器的时间设置到slider上,实现进度显示。

- (void)setProgressTime:(CGFloat)currentTime totalTime:(CGFloat)totalTime playableValue:(CGFloat)playable
{
    if (!self.vodSlider.isDragging) {
        //总时长
        self.vodTotalTimeLabel.text = [PlayerSkinTool timeFormat:totalTime];
        //更新当前播放时间
        self.vodCurrentTimeLabel.text = [PlayerSkinTool timeFormat:currentTime];
        // 更新slider
        self.vodSlider.maximumValue = totalTime;
        self.vodSlider.minimumValue = 0.0;
        self.vodSlider.value        = currentTime;
    }
    //更新缓存时长
    [self.vodSlider.progressView setProgress:playable/totalTime animated:NO];
}

注意事项

滑块进度与点播播放器的事件要保持同步,滑动滑块,播放器seek,如果发现seek后滑块会往回“跳”的情况,大多数是没同步导致的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Morris_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值