UISlider是開發(fā)中不太常用到的一種基礎(chǔ)控件。雖然不常用到, 但是我們卻常見到:
手機(jī)系統(tǒng)設(shè)置里->顯示與亮度,就有這樣的一個(gè)slider:

系統(tǒng)的UISlider創(chuàng)建出來(lái)也是如此。
但是在實(shí)際開發(fā)中, 設(shè)計(jì)師根據(jù)產(chǎn)品風(fēng)格設(shè)計(jì)出不同的slider樣式后, 這很多人都選擇直接去自定義view來(lái)實(shí)現(xiàn)效果, 其實(shí)這樣超麻煩!
自定義的slider無(wú)外乎就是最大最小值的樣式, 滑塊的樣式,以及滑竿的樣式等。
這樣自定義完成可以依靠UISlider的API來(lái)實(shí)現(xiàn):
// 默認(rèn)為nil, 控件左側(cè)的圖像
@property(nullable, nonatomic,strong) UIImage *minimumValueImage;
// 默認(rèn)為nil, 控件右側(cè)的圖像
@property(nullable, nonatomic,strong) UIImage *maximumValueImage;
// 滑塊左邊線條的圖像
- (void)setMinimumTrackImage:(nullable UIImage *)image forState:(UIControlState)state;
// 滑塊右邊線條的圖像
- (void)setMaximumTrackImage:(nullable UIImage *)image forState:(UIControlState)state;
// 滑塊左邊線條的顏色
@property(nullable, nonatomic,strong) UIColor *minimumTrackTintColor;
// 滑塊右邊線條的顏色
@property(nullable, nonatomic,strong) UIColor *maximumTrackTintColor;
/**
* 這里有個(gè)小重點(diǎn):
* 如果即設(shè)置了滑塊的圖像,又設(shè)置了滑塊的顏色,那么滑塊的圖像將不再顯示,滑塊的顏色會(huì)發(fā)生改變。
**/
// 滑塊的圖像
- (void)setThumbImage:(nullable UIImage *)image forState:(UIControlState)state;
// 滑塊的顏色
@property(nullable, nonatomic,strong) UIColor *thumbTintColor;
以上的這些API都是對(duì)UISlider進(jìn)行UI上的修改。
但常常大家會(huì)發(fā)現(xiàn), 設(shè)置完成后, 左右圖像的大小, 滑塊的大小, 滑竿的高度等等都和設(shè)計(jì)圖不符, 特別是滑竿距離左右兩邊的圖像還有一定的空隙。
不需要著急, 此時(shí)只需要?jiǎng)?chuàng)建一個(gè)UISlider的子類,并重寫這幾個(gè)方法:
// 左右兩側(cè)圖像尺寸
- (CGRect)minimumValueImageRectForBounds:(CGRect)bounds;
- (CGRect)maximumValueImageRectForBounds:(CGRect)bounds;
// 滑條尺寸
- (CGRect)trackRectForBounds:(CGRect)bounds;
// 滑塊尺寸
- (CGRect)thumbRectForBounds:(CGRect)bounds trackRect:(CGRect)rect value:(float)value;
先看一個(gè)對(duì)比效果圖,上面為UISlider, 下面為繼承UISlider的子類:

直接上代碼:
- 創(chuàng)建UISlider子類,并重寫滑條尺寸
#import "LWSlider.h"
@implementation LWSlider
// 設(shè)置track(滑條)尺寸
- (CGRect)trackRectForBounds:(CGRect)bounds{
bounds.origin.y = (bounds.size.height - 2)/2.0;
bounds.size.height = 2;
return bounds;
}
@end
- 創(chuàng)建LWSlider對(duì)象, 并設(shè)置對(duì)應(yīng)的圖像
- (LWSlider *)slider2{
if (!_slider2) {
_slider2 = [[LWSlider alloc] init];
_slider2.minimumValue = 0;
_slider2.maximumValue = _slider2Numbers.count - 2;
_slider2.value = 3;
_slider2.minimumValueImage = GetImage(@"slider-min");
_slider2.maximumValueImage = GetImage(@"slider-max");
_slider2.minimumTrackTintColor = BtnBgColor;
_slider2.maximumTrackTintColor = UIColorFromHEXA(0xE5E5E5, 1.0);
[_slider2 setThumbImage:GetImage(@"slider") forState:UIControlStateNormal];
[_slider2 addTarget:self action:@selector(slidervalueDidChanged:) forControlEvents:UIControlEventValueChanged];
}
return _slider2;
}
寫到這里就可以自定義一個(gè)想要的slider了, 但是有些產(chǎn)品會(huì)要求, slider滑動(dòng)時(shí)要有一定的間隔, 比如,每滑動(dòng)一次就直接過(guò)5%?
遇到這樣的情況又要怎么做呢?
我在網(wǎng)上看到有人用長(zhǎng)度計(jì)算的方式, 在UIControlEventValueChanged事件里根據(jù)當(dāng)前滑動(dòng)值去進(jìn)行一大堆的數(shù)學(xué)計(jì)算, 然后重新設(shè)置slider的value值。
這樣寫雖然也達(dá)到了其想要的效果, 但是很麻煩。
下面給大家介紹一個(gè)簡(jiǎn)單的方法:
- 創(chuàng)建一個(gè)滑動(dòng)值數(shù)組
_slider2Numbers = [[NSMutableArray alloc] init];
for (int i = -1; i < 25; ++i) {
[_slider2Numbers addObject:@(i * 0.5)];
}
- 設(shè)置slider的最大最小值
_slider2.minimumValue = 0;
_slider2.maximumValue = _slider2Numbers.count - 2;
- 在
UIControlEventValueChanged事件里進(jìn)行處理
當(dāng)slider滑動(dòng)時(shí), 將slider.value作為索引值,去獲取滑動(dòng)值數(shù)組里相對(duì)應(yīng)索引位置的數(shù)值, 并將其設(shè)置到界面上
- (void)slidervalueDidChanged:(UISlider *)slider{
NSString *value = [_slider2Numbers objectAtIndex:slider.value + 1];
self.subTitleLab2.text = [NSString stringWithFormat:@"%@h",value];
}
滑動(dòng)間隔固定處理效果如下圖:

以上,END。
