最近有个需求, App
内需要一个 RGB
的 拾色器
. 网上也没有找到好的轮子, 只好自己造一个了.
轮子的大概效果是这样子的:
UISlider 动态渐变背景
UISlider
类本身仅仅为开发者提供了 4 个属性来设置其背景样式:
1
2
3
4
5
6
7
8
// 滑块左面背景图片
@property(nullable, nonatomic,strong) UIImage *minimumValueImage;
// 滑块右面背景图片
@property(nullable, nonatomic,strong) UIImage *maximumValueImage;
// 滑块左面背景颜色
@property(nullable, nonatomic,strong) UIColor *minimumTrackTintColor;
// 滑块右面背景颜色
@property(nullable, nonatomic,strong) UIColor *maximumTrackTintColor;
以及若干方法, 但是效果跟上面 4 个属性效果差不多.
实现动态的渐变背景只能通过 自定义
来完成了.
系统有专门为做渐变而封装的 CAGradientLayer
类.
此处就用 CAGradientLayer
来做 UISlider
的渐变背景.
我们的自定义视图层级如下结构所示:
1
2
3
UIView (父视图)
|- CAGradientLayer (渐变背景)
|- UISlider (滑动视图)
创建一个 ZHKColorSlider
类, 为我们的动态渐变背景的 Slider 类.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
typedef void(^ColorSliderChangedBlock)(CGFloat value);
@interface ZHKColorSlider : UIView
// 当前 Slider 的值
@property (nonatomic, assign) CGFloat value;
// Slider 值改变时候的回调
@property (nonatomic, copy) ColorSliderChangedBlock changedBlock;
// 滑动视图
@property (nonatomic, strong) UISlider *slider;
// 背景渐变图层
@property (nonatomic, strong) CAGradientLayer *backLayer;
/**
设置背景由左向右的渐变颜色
@param startColor 开始颜色 (左侧)
@param endColor 结束颜色 (右侧)
*/
- (void)startColor:(UIColor *)startColor endColor:(UIColor *)endColor;
@end
注意点
- 设置
UISlider
的minimumTrackTintColor
和maximumTrackTintColor
为clearColor
. 防止影响我们自定义的渐变背景效果. - UISlider 的设置:
1 2 3 4
// 这样设置方便颜色的取值 // 不一定非要这个设置, 只是为了方便取值和转换. _slider.minimumValue = 0.0f; _slider.maximumValue = 255.0f;
backLayer
背景渐变图层的设置:1 2 3 4
// 设置渐变的方向为从 左 向 右 _backLayer.startPoint = CGPointMake(0, 0); _backLayer.endPoint = CGPointMake(1, 0); _backLayer.locations = @[@0.0, @1.0];
不贴过多的代码, 只写一下 原理
和 注意点
. 下面会放 demo
地址.
调色器
调色器
为 3
个背景可以动态渐变的 Slider
组成. 且 3 个 Slider
之间有联动效果. 最终结合 3 个 Slider 的值生成我们的结果即可达成我们的目的.
创建 ZHKSliderColorPicker
类, 作为 滑动视图
和 联动效果
的封装.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@class ZHKSliderColorPicker;
@protocol ColorSliderPickerDelegate <NSObject>
- (void)picker:(ZHKSliderColorPicker *)picker color:(UIColor *)color;
@end
@interface ZHKSliderColorPicker : UIView
// 当前拾色器的颜色
@property (nonatomic, strong) UIColor *color;
// R 滑动视图
@property (nonatomic, strong) ZHKColorSlider *RSlider;
// G 滑动视图
@property (nonatomic, strong) ZHKColorSlider *GSlider;
// B 滑动视图
@property (nonatomic, strong) ZHKColorSlider *BSlider;
// 即时回调代理
@property (nonatomic, weak) id <ColorSliderPickerDelegate> delegate;
@end
属性 color
的 Setter
用于设置调色器 当前颜色
和 滑动视图的联动分布
. Getter
用于获取当前的 调色结果
.
滑动视图的联动
RSlider
, GSlider
, BSlider
任意一个值得变化, 都会造成另外 2
个 Slider
背景颜色的变化.
因此此处在 Slider
的值发生改变的时候, 需要在其回调方法内调用其他 2 个 Slider
的方法:
1
- (void)startColor:(UIColor *)startColor endColor:(UIColor *)endColor
回调方法的联动逻辑以 RSlider
的回调为例:
1
2
3
4
- (void)redAction:(CGFloat)value {
[_GSlider startColor:COLOR(_RSlider.value, 0, _BSlider.value, 1) endColor:COLOR(_RSlider.value, 255, _BSlider.value, 1)];
[_BSlider startColor:COLOR(_RSlider.value, _GSlider.value, 0, 1) endColor:COLOR(_RSlider.value, _GSlider.value, 255, 1)];
}
GSlider
和 BSlider
的回调方法与 RSlider
逻辑相同, 举一反三即可.
其中 COLOR
宏如下:
1
2
// 通过 RGB 创建颜色对象
#define COLOR(R, G, B, A) [UIColor colorWithRed:R / 255.0 green:G / 255.0 blue:B / 255.0 alpha:A]
如果需要即时获取当前调色器的颜色结果, 在联动方法的末尾 回调代理
即可.
注意点:
Slider
的value
范围是0 ~ 255
, 因此在数据处理的时候需要注意.- 由外部给
color
属性赋值的时候, 不仅要改变Slider
的value
, 还要改变其渐变背景
, 使其视觉效果和数值在逻辑上达到统一.