iOS UISlider自定義漸變色滑桿

前言

  • 本文主要介紹繼承實現自定義漸變色滑桿,空心滑桿
GitHub地址:KJExtensionHandler

簡單介紹 Property & API

@interface KJColorSlider : UISlider
/// 顏色數組,默認白色
@property(nonatomic,strong) NSArray<UIColor*>*colors;
/// 每個顏色對應的位置信息
@property(nonatomic,strong) NSArray<NSNumber*>*locations;
/// 顏色的高度,默認2.5px
@property(nonatomic,assign) CGFloat colorHeight;
/// 邊框寬度,默認0px
@property(nonatomic,assign) CGFloat borderWidth;
/// 邊框顏色,默認黑色
@property(nonatomic,strong) UIColor *borderColor;
/// 回調處理時間,默認爲0
@property(nonatomic,assign) float timeSpan;
/// 當前進度,用於外界kvo
@property(nonatomic,assign,readonly) CGFloat progress;
/// 移動回調處理
@property(nonatomic,readwrite,copy) void(^kValueChangeBlock)(CGFloat progress);
/// 移動結束回調處理
@property(nonatomic,readwrite,copy) void(^kMoveEndBlock)(CGFloat progress);
/// 重新設置UI
- (void)kj_setUI;

@end
1. colors和locations配合使用實現漸變色
/// 彩虹漸變色滑桿
slider2.colors = @[UIColorFromHEXA(0xFF0000,1),
                   UIColorFromHEXA(0xFF7F00,1),
                   UIColorFromHEXA(0xFFFF00,1),
                   UIColorFromHEXA(0x00FF00,1),
                   UIColorFromHEXA(0x00FFFF,1),
                   UIColorFromHEXA(0x0000FF,1),
                   UIColorFromHEXA(0x8B00FF,1)];
slider2.locations = @[@0.,@0.16,@(0.16*2),@(0.16*3),@(0.16*4),@(0.16*5),@1.];
/// 飽和度滑桿
slider.colors = @[UIColorFromHEXA(0xF44336,1), UIColorFromHEXA(0xFFFFFF,1)];
slider.locations = @[@0.,@0.8];
2. colorHeight滑桿的高度,內部那條線而非整體的高度
3. borderWidth和borderColor邊框相關
4. timeSpan回調間隔時間限制

這裏主要用於很多時候在不停滑動的過程當中,會頻繁觸發內部的方法。所以寫這個參數來控制kValueChangeBlock回調的觸發頻率

5. progress當前進度,相當於self.value

這個參數主要用於外界kvo

/// kvo
[slider kj_observeKey:@"progress" ObserveResultBlock:^(id  _Nonnull newValue, id  _Nonnull oldValue) {
    NSLog(@"%@",newValue);
}];
6. kValueChangeBlock和kMoveEndBlock

kValueChangeBlock:滑動過程當中調用
kMoveEndBlock:滑動結束或者異常中斷調用

slider.kValueChangeBlock = ^(CGFloat progress) {
    NSLog(@"progress:%f",progress);
};
slider.kMoveEndBlock = ^(CGFloat progress) {
    NSLog(@"end:%f",progress);
};
7. kj_setUI重設UI調用
附上完整實現
#import "KJColorSlider.h"
#import "UIColor+KJExtension.h"
@interface KJColorSlider()
@property(nonatomic,strong) UIImageView *backImageView;
@property(nonatomic,assign) NSTimeInterval lastTime;
@property(nonatomic,assign) CGFloat progress;
@end

@implementation KJColorSlider
#pragma mark - public method
- (void)kj_setUI{ [self drawNewImage];}

#pragma mark - system method
- (void)awakeFromNib{
    [super awakeFromNib];
    [self setup];
}
- (instancetype)initWithFrame:(CGRect)frame{
    if (self == [super initWithFrame:frame]) {
        [self setup];
    }
    return self;
}
- (void)layoutSubviews{
    [super layoutSubviews];
    if (CGRectEqualToRect(self.backImageView.frame, CGRectZero)) {
        CGRect imgViewFrame = self.backImageView.frame;
        imgViewFrame.size.width = self.frame.size.width;
        imgViewFrame.size.height = self.colorHeight;
        imgViewFrame.origin.y = (self.frame.size.height - self.colorHeight) * 0.5;
        self.backImageView.frame = imgViewFrame;
        [self drawNewImage];
    }
}
#pragma mark - private method
- (void)drawNewImage{
    self.backImageView.image = [UIColor kj_colorImageWithColors:_colors locations:_locations size:CGSizeMake(self.frame.size.width, _colorHeight) borderWidth:_borderWidth borderColor:_borderColor];
    self.progress = self.value;
}
- (void)setup{
    self.colors = @[UIColor.whiteColor];
    self.locations = @[@(1.)];
    self.colorHeight = 2.5;
    self.borderWidth = 0.0;
    self.borderColor = UIColor.blackColor;
    self.backImageView = [[UIImageView alloc] initWithFrame:CGRectZero];
    [self addSubview:self.backImageView];
    [self sendSubviewToBack:self.backImageView];
    self.tintColor = [UIColor clearColor];
    self.maximumTrackTintColor = self.minimumTrackTintColor = [UIColor clearColor];
    [self addTarget:self action:@selector(valueChange) forControlEvents:UIControlEventValueChanged];
    [self addTarget:self action:@selector(endMove) forControlEvents:UIControlEventTouchUpInside];
    [self addTarget:self action:@selector(endMove) forControlEvents:UIControlEventTouchUpOutside];
    [self addTarget:self action:@selector(touchCancel) forControlEvents:UIControlEventTouchCancel];
}
- (void)valueChange{
    self.progress = self.value;
    if (self.kValueChangeBlock) {
        if (_timeSpan == 0) {
            self.kValueChangeBlock(self.value);
        }else if (CFAbsoluteTimeGetCurrent() - self.lastTime > _timeSpan) {
            _lastTime = CFAbsoluteTimeGetCurrent();
            self.kValueChangeBlock(self.value);
        }
    }
}
- (void)endMove{
    self.progress = self.value;
    if (self.kMoveEndBlock) {
        self.kMoveEndBlock(self.value);
        return;
    }
    if (self.kValueChangeBlock) self.kValueChangeBlock(self.value);
}
- (void)touchCancel{
    self.progress = self.value;
    if (self.kMoveEndBlock) self.kMoveEndBlock(self.value);
}

@end
示例代碼
__block KJColorSlider *slider = [[KJColorSlider alloc]initWithFrame:CGRectMake(20, 100, kScreenW-40, 30)];
slider.value = 0.5;
[self.view addSubview:slider];
slider.colors = @[UIColorFromHEXA(0xF44336,1), UIColorFromHEXA(0xFFFFFF,1)];
slider.locations = @[@0.,@0.8];
slider.kValueChangeBlock = ^(CGFloat progress) {
    NSLog(@"progress:%f",progress);
};
slider.kMoveEndBlock = ^(CGFloat progress) {
    NSLog(@"end:%f",progress);
};

KJColorSlider *slider2 = [[KJColorSlider alloc] initWithFrame:CGRectMake(20, slider.bottom+30, kScreenW-40, 30)];
slider2.value = 0.5;
slider2.colors = @[UIColorFromHEXA(0xFF0000,1),
                   UIColorFromHEXA(0xFF7F00,1),
                   UIColorFromHEXA(0xFFFF00,1),
                   UIColorFromHEXA(0x00FF00,1),
                   UIColorFromHEXA(0x00FFFF,1),
                   UIColorFromHEXA(0x0000FF,1),
                   UIColorFromHEXA(0x8B00FF,1)];
slider2.locations = @[@0.,@0.16,@(0.16*2),@(0.16*3),@(0.16*4),@(0.16*5),@1.];
[self.view addSubview:slider2];

KJColorSlider *slider3 = [[KJColorSlider alloc] initWithFrame:CGRectMake(20, slider2.bottom+30, kScreenW-40, 30)];
slider3.colorHeight = 28;
slider3.borderColor = UIColor.redColor;
slider3.borderWidth = 1.5;
slider3.value = 0.5;
[self.view addSubview:slider3];

/// kvo
[slider kj_observeKey:@"progress" ObserveResultBlock:^(id  _Nonnull newValue, id  _Nonnull oldValue) {
    NSLog(@"%@",newValue);
}];
[slider2 kj_observeKey:@"progress" ObserveResultBlock:^(id  _Nonnull newValue, id  _Nonnull oldValue) {
    NSLog(@"---%@",newValue);
}];
備註:本文用到的部分函數方法和Demo,均來自三方庫KJExtensionHandler,如有需要的朋友可自行pod 'KJExtensionHandler'引入即可

自定義漸變色滑桿介紹就到此完畢,後面有相關再補充,寫文章不容易,還請點個小星星傳送門

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章