前言
- 这里实现的是一个圆环形式的Slider滑动条效果。封装了EFCircularSlider类,利用该类可实现的效果有:基本的圆环滑动效果、双重圈滑动点的圆环滑动条效果,以及当下流行的滑动选择时间效果。
EFCircularSlider框架简介
- 由于滑块是一个标准的UIControl,所以EFCircularSlider是一个集成UIControl的类。
- 该类绘制了两个空心圆,一个作为初始滑动条,一个用来填充滑动条,手柄拖动时,根据三角函数计算出当前手柄点所在的地方,绘制弧线,覆盖在原初始滑动条之上。滑动手柄的样式可选择,还可根据需要添加文字标签,优美的改变了UISlider的外观。
- 滑块的实现通过UIControl的以下协议方法:
- //开始跟踪触摸
- -(BOOL) beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event;
- //继续跟踪触摸
- -(BOOL) continueTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event;
- //结束跟踪触摸
- -(void)endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event;
- //开始跟踪触摸
#pragma mark - UIControl functions
//开始跟踪触摸
-(BOOL) beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event {
[super beginTrackingWithTouch:touch withEvent:event];
return YES;
}
//继续跟踪触摸
-(BOOL) continueTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event {
[super continueTrackingWithTouch:touch withEvent:event];
CGPoint lastPoint = [touch locationInView:self];
[self moveHandle:lastPoint];
[self sendActionsForControlEvents:UIControlEventValueChanged];
return YES;
}
//结束跟踪触摸
-(void)endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event {
[super endTrackingWithTouch:touch withEvent:event];
if(_snapToLabels && labelsEvenSpacing != nil) {
CGPoint bestGuessPoint;
float minDist = 360; //距离
for (int i=0; i<[labelsEvenSpacing count]; i++) {
//在圆上得百分比
CGFloat percentageAlongCircle = i/(float)[labelsEvenSpacing count];
//度数
CGFloat degreesForLabel = percentageAlongCircle * 360;
if(abs(fixedAngle - degreesForLabel) < minDist) {
minDist = abs(fixedAngle - degreesForLabel);
bestGuessPoint = [self pointFromAngle:degreesForLabel + 90 + 180];
}
}
CGPoint centerPoint = CGPointMake(self.frame.size.width/2, self.frame.size.height/2);
angle = floor(AngleFromNorth(centerPoint, bestGuessPoint, NO));
_currentValue = [self valueFromAngle];
[self setNeedsDisplay];
}
}
EFCircularSlider框架的使用
- 导入框架:
#import "EFCircularSlider.h"
- 基本用法:
EFCircularSlider* circularSlider = [[EFCircularSlider alloc] initWithFrame:CGRectMake(50, 180, 220, 220)];
[circularSlider addTarget:self action:@selector(valueChanged:) forControlEvents:UIControlEventValueChanged];
[self.view addSubview:circularSlider];
上述代码就能实现
EFCircularSlider框架中封装的功能,使用简单,效果优美。
- 定义全局变量:
EFCircularSlider *_minuteSlider;
EFCircularSlider *_hourSlider;
- 初始化Slider
_minuteSlider = [[EFCircularSlider alloc] initWithFrame:CGRectMake(10, 170, 300, 300)];
_hourSlider = [[EFCircularSlider alloc] initWithFrame:CGRectMake(55, 220, 210, 210)];
- 访问UISlider的值
_minuteSlider.lineWidth = 8; //设置线宽
_minuteSlider.minimumValue = 0; //设置最小值
_minuteSlider.maximumValue = 60; //设置最大值
_hourSlider.lineWidth = 12; //设置线宽
_hourSlider.minimumValue = 0; //设置最小值
_hourSlider.maximumValue = 12; //设置最大值
_hourSlider.snapToLabels = NO; //设置标签不对齐
- 改变Slider外观显示的颜色
_minuteSlider.unfilledColor = [UIColor colorWithRed:23/255.0f green:47/255.0f blue:70/255.0f alpha:1.0f];
_minuteSlider.filledColor = [UIColor colorWithRed:155/255.0f green:211/255.0f blue:156/255.0f alpha:1.0f];
_hourSlider.unfilledColor = [UIColor colorWithRed:23/255.0f green:47/255.0f blue:70/255.0f alpha:1.0f];
_hourSlider.filledColor = [UIColor colorWithRed:98/255.0f green:243/255.0f blue:252/255.0f alpha:1.0f];
- 设置文字标签
[_minuteSlider setInnerMarkingLabels:@[@"5", @"10", @"15", @"20", @"25", @"30", @"35", @"40", @"45", @"50", @"55", @"60"]];
_minuteSlider.labelFont = [UIFont systemFontOfSize:14.0f];
_minuteSlider.labelColor = [UIColor colorWithRed:76/255.0f green:111/255.0f blue:137/255.0f alpha:1.0f];
[_hourSlider setInnerMarkingLabels:@[@"1", @"2", @"3", @"4", @"5", @"6", @"7", @"8", @"9", @"10", @"11", @"12"]];
_hourSlider.labelFont = [UIFont systemFontOfSize:14.0f];
_hourSlider.labelColor = [UIColor colorWithRed:127/255.0f green:229/255.0f blue:255/255.0f alpha:1.0f];
- 改变手柄样式
_minuteSlider.handleType = doubleCircleWithOpenCenter;
_minuteSlider.handleColor = _minuteSlider.filledColor;
_hourSlider.handleType = bigCircle;
_hourSlider.handleColor = _hourSlider.filledColor;
- 设置Slider的行为
[_minuteSlider addTarget:self action:@selector(minuteDidChange:) forControlEvents:UIControlEventValueChanged];
[_hourSlider addTarget:self action:@selector(hourDidChange:) forControlEvents:UIControlEventValueChanged];
为Slider添加方法,当Slider的值改变时就会触发该方法。
效果图: