123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251 |
- //
- // CYCircularSlider.m
- // CYCircularSlider
- //
- // Created by user on 2018/3/23.
- // Copyright © 2018年 com. All rights reserved.
- //
- #import "CYCircularSlider.h"
- #define ToRad(deg) ( (M_PI * (deg)) / 180.0 ) //半圆弧度
- #define ToDeg(rad) ( (180.0 * (rad)) / M_PI )
- #define SQR(x) ( (x) * (x) )
- @implementation CYCircularSlider{
- int _angle;
- CGFloat radius;
- CGFloat _currentValue;// 档位
- int _fixedAngle;
- }
- -(instancetype)initWithFrame:(CGRect)frame{
- self = [super initWithFrame:frame];
- if (self) {
-
- CGFloat height = self.frame.size.height;
-
- _maximumValue = 10.0f;
- _minimumValue = 0.0f;
- _currentValue = 0.0f;
- _lineWidth = 5.0f;
- _unfilledColor = [UIColor colorWithRed:250/255.0f green:60/255.0f blue:20/255.0f alpha:1.0f];
- _filledColor = [UIColor colorWithRed:175/255.0f green:195/255.0f blue:5/255.0f alpha:1.0f];
- _handleColor = UIColor.whiteColor;
- _handleColor2 = RDSGreenColor;
- _handleColor3 = UIColor.clearColor;
- radius = self.frame.size.height/2 - _lineWidth/2-10;// 半径 决定大小
- _angle = 140;
- self.backgroundColor = [UIColor clearColor];
- }
-
- return self;
- }
- - (void)setLineWidth:(int)lineWidth{
- _lineWidth = lineWidth;
- radius = self.frame.size.height/2 - _lineWidth/2-10;// 半径 决定大小
- }
- #pragma mark 画圆
- // CGContextAddArc(Context, CGFloat x , CGFloat y, CGFloat radius, CGFloat startAngle , CGFloat endAngle, int clockwise);
- // 关于角度,由x,y可确定圆心坐标,而0,0角度位于圆心的正下方。
- // startAngle是由0,0偏移的。
- // 偏移方向是由clockwise控制的,0为顺时针,1为逆时针。
- -(void)drawRect:(CGRect)rect{
- [super drawRect:rect];
-
- CGFloat x = self.frame.size.width/2;
- CGFloat y = self.frame.size.height/2;
-
- //画固定的下层圆
- CGContextRef ctx = UIGraphicsGetCurrentContext();
- CGContextAddArc(ctx, x, y, radius, M_PI/180*140, M_PI/180*40, 0);
- [_unfilledColor setStroke];
- CGContextSetLineWidth(ctx, _lineWidth);
- CGContextSetLineCap(ctx, kCGLineCapRound);
- CGContextDrawPath(ctx, kCGPathStroke);
-
- //画可滑动的上层圆
- CGContextAddArc(ctx, x, y, radius, M_PI/180*140, M_PI/180*(_angle), 0);
- [_filledColor setStroke];
- CGContextSetLineWidth(ctx, _lineWidth);
- CGContextSetLineCap(ctx, kCGLineCapRound);
- CGContextDrawPath(ctx, kCGPathStroke);
-
- // 画按钮
- [self drawHandle:ctx];
-
- }
- #pragma mark 画按钮
- -(void)drawHandle:(CGContextRef)ctx{
- CGContextSaveGState(ctx);
-
- // 阴影
- UIColor *shadowColor = [UIColor colorWithRed:0/255.0 green:0/255.0 blue:0/255.0 alpha:0.2000];
- CGContextSaveGState(ctx);
- CGContextSetShadowWithColor(ctx, CGSizeMake(0,4.4), 11.1, shadowColor.CGColor);
-
- // 大圆点
- CGPoint handleCenter = [self pointFromAngle: _angle];
- [_handleColor set];
- CGContextFillEllipseInRect(ctx, CGRectMake(handleCenter.x-8, handleCenter.y-8, _lineWidth+16, _lineWidth+16));
- CGContextRestoreGState(ctx);
-
-
- // 中间小圆点
- CGFloat width = 18;
- CGContextSaveGState(ctx);
- [_handleColor2 set];
- CGContextFillEllipseInRect(ctx, CGRectMake(handleCenter.x-(width-_lineWidth)/2, handleCenter.y-(width-_lineWidth)/2, width, width));
- CGContextRestoreGState(ctx);
-
- // 和线一样宽度的圆点,默认透明隐藏,设置了_handleColor3颜色才显示
- CGContextSaveGState(ctx);
- [_handleColor3 set];
- CGContextFillEllipseInRect(ctx, CGRectMake(handleCenter.x, handleCenter.y, _lineWidth, _lineWidth));
- CGContextRestoreGState(ctx);
- }
- -(CGPoint)pointFromAngle:(int)angleInt{
-
- //Define the Circle center
- CGPoint centerPoint = CGPointMake(self.frame.size.width/2 - _lineWidth/2, self.frame.size.height/2 - _lineWidth/2);
- //Define The point position on the circumference
- CGPoint result;
- result.y = round(centerPoint.y + radius * sin(ToRad(angleInt))) ;
- result.x = round(centerPoint.x + radius * cos(ToRad(angleInt)));
-
- return result;
- }
- -(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];
-
- //用于排除点在圆外面点与圆心半径80以内的点
- // if ((lastPoint.x>=0&&lastPoint.x<=275)&&(lastPoint.y>=0 && lastPoint.y<=275)) {
-
- // if ((lastPoint.x<=57.5 ||lastPoint.x>=217.5)||(lastPoint.y<=57.5 ||lastPoint.y>=217.5)) {
- [self moveHandle:lastPoint];
- // }
- // }
- [self sendActionsForControlEvents:UIControlEventValueChanged];
- return YES;
- }
- -(void)moveHandle:(CGPoint)point {
- CGPoint centerPoint = CGPointMake(self.frame.size.width/2, self.frame.size.height/2);
- int currentAngle = floor(AngleFromNorth(centerPoint, point, NO));
- if (currentAngle>40 && currentAngle <140) {
-
- }else{
- if (currentAngle<=40) {
- _angle = currentAngle+360;
- }else{
- _angle = currentAngle;
- }
-
- }
- _currentValue =[self valueFromAngle];
- [self setNeedsDisplay];
-
- }
- static inline float AngleFromNorth(CGPoint p1, CGPoint p2, BOOL flipped) {
- CGPoint v = CGPointMake(p2.x-p1.x,p2.y-p1.y);
- float vmag = sqrt(SQR(v.x) + SQR(v.y)), result = 0;
- v.x /= vmag;
- v.y /= vmag;
- double radians = atan2(v.y,v.x);
- result = ToDeg(radians);
- return (result >=0 ? result : result + 360.0);
- }
- //在这个地方调整进度条
- -(float) valueFromAngle {
- CGFloat curValue = _currentValue;
- if(_angle <= 40) {
- curValue = 220+_angle;
- } else if(_angle>40 && _angle < 140){
-
- }else{
- curValue = _angle-100-40;
- }
- _fixedAngle = curValue;
-
- CGFloat value = (curValue*(_maximumValue - _minimumValue))/260.0f;
-
- // 四舍五入 档位
- int a;
- a = (int)(value + 0.5);
- _angle = (int)260/(_maximumValue - _minimumValue)*a+140;
-
- if(a != _currentValue){
- _currentValue = a;// 档位
- _value = (int)(a+_minimumValue);// 用户设置的值
- //DDLog(@"Value:%d",_value);
- [self.delegate senderVlueChangingWithNum:_value];
- }
- return a;
- }
- -(void)endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event{
- [super endTrackingWithTouch:touch withEvent:event];
-
- [self.delegate senderVlueWithNum:_value];
- }
- #pragma mark 设置进度条位置
- - (void)setValue:(int)value{
- _value = value;
- if(value > _maximumValue){
- _currentValue = _maximumValue - _minimumValue;
- }else if (value < _minimumValue){
- _currentValue = 0;
- }else{
- _currentValue = value - _minimumValue;
- }
-
-
- _angle = (int)260/(_maximumValue - _minimumValue)*_currentValue+140;
- [self setNeedsDisplay];
- }
- -(void)setAddAngel{
- _angle += (int)260/(_maximumValue - _minimumValue);
- if (_angle>400) {
- _angle = 400;
- }
- [self setNeedsDisplay];
-
-
- _currentValue =[self valueFromAngle];
- }
- -(void)setMovAngel{
- _angle -= (int)260/(_maximumValue - _minimumValue);
- if (_angle<140) {
- _angle = 140;
- }
- [self setNeedsDisplay];
-
-
- _currentValue =[self valueFromAngle];
- }
- @end
|