IOS编程开发教程:ios双拉杆
程序员文章站
2022-03-08 15:10:09
IOS编程开发教程:ios双拉杆,有机会 我将 开源 android 同样的组件。
//
// EFCircularSlider.m
// Awake...
IOS编程开发教程:ios双拉杆,有机会 我将 开源 android 同样的组件。
// // EFCircularSlider.m // Awake // // Created by Eliot Fowler on 12/3/13. // Copyright (c) 2013 Eliot Fowler. All rights reserved. // #import "EFCircularSlider.h" #import #import #define ToRad(deg) ( (M_PI * (deg)) / 180.0 ) #define ToDeg(rad) ( (180.0 * (rad)) / M_PI ) #define SQR(x) ( (x) * (x) ) @implementation EFCircularSlider { CGFloat radius; int angle1; int angle2; int fixedAngle; NSMutableDictionary* labelsWithPercents; NSArray* labelsEvenSpacing; } - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { // Defaults _maximumValue = 100.0f; _minimumValue = 0.0f; _currentValue1 = 0.0f; _lineWidth = 55; _unfilledColor = [UIColor redColor]; _filledColor1 = [UIColor redColor]; _filledColor2 = [UIColor orangeColor]; _handleColor = [UIColor whiteColor]; _handleInColor1=_filledColor1; _handleInColor2=_filledColor2; _labelFont = [UIFont systemFontOfSize:10.0f]; _snapToLabels = NO; _handleType = semiTransparentWhiteCircle; _labelColor = [UIColor redColor]; // angle1=360 - (360-165) - 15; // _currentValue1=100; // _currentValue2=100; // angle2=360-(360-30)-150; angle1= 0; _currentValue1=0; _currentValue2=0; angle2=0; radius = self.frame.size.height/2 - _lineWidth/2; self.backgroundColor = [UIColor clearColor]; } return self; } -(void)layoutSubviews{ [super layoutSubviews]; int totalAngle1 = 360 -165 +15; int currentAngle1 =0; float percentAngle1 = totalAngle1 * (_currentValue1/_maximumValue); if (percentAngle1<=(360-165)) { currentAngle1 = 165 + percentAngle1; }else{ currentAngle1 = percentAngle1 - (360-165); } angle1 = 360 - (360-165) - currentAngle1; int totalAngle2 = 150-30; int currentAngle2=0; float percentAngle2 = totalAngle2 * (_currentValue2/_maximumValue); currentAngle2 = 30+percentAngle2; angle2=360-(360-30)-currentAngle2; } #pragma mark - drawing methods - (void)drawRect:(CGRect)rect { [super drawRect:rect]; CGContextRef ctx = UIGraphicsGetCurrentContext(); //Draw the unfilled circle // CGContextAddArc(ctx, self.frame.size.width/2, self.frame.size.height/2, radius, 0, M_PI *2, 0); CGContextAddArc(ctx, self.frame.size.width/2 , self.frame.size.height/2, radius, 165*M_PI/180, ToRad(15), 0); [_unfilledColor setStroke]; CGContextSetLineWidth(ctx, _lineWidth); CGContextSetLineCap(ctx, kCGLineCapButt); CGContextDrawPath(ctx, kCGPathStroke); CGContextAddArc(ctx, self.frame.size.width/2 , self.frame.size.height/2, radius, M_PI/6,M_PI/6-ToRad(-120), 0); [_unfilledColor setStroke]; CGContextSetLineWidth(ctx, _lineWidth); CGContextSetLineCap(ctx, kCGLineCapButt); CGContextDrawPath(ctx, kCGPathStroke); //Draw the filled circle // if((_handleType == doubleCircleWithClosedCenter || _handleType == doubleCircleWithOpenCenter) && fixedAngle > 5) { //// CGContextAddArc(ctx, self.frame.size.width/2 , self.frame.size.height/2, radius, 3*M_PI/2, 3*M_PI/2-ToRad(angle+3), 0); // CGContextAddArc(ctx, self.frame.size.width/2 , self.frame.size.height/2, radius, 165*M_PI/180, 165*M_PI/180-ToRad(angle1+3), 0); // [_filledColor setStroke]; // CGContextSetLineWidth(ctx, _lineWidth); // CGContextSetLineCap(ctx, kCGLineCapButt); // CGContextDrawPath(ctx, kCGPathStroke); // CGContextAddArc(ctx, self.frame.size.width/2, self.frame.size.height/2, radius, M_PI/6, M_PI/6-ToRad(angle2+3), 0); // [_filledColor setStroke]; // CGContextSetLineWidth(ctx, _lineWidth); // CGContextSetLineCap(ctx, kCGLineCapButt); // CGContextDrawPath(ctx, kCGPathStroke); // } else { // CGContextAddArc(ctx, self.frame.size.width/2 , self.frame.size.height/2, radius, 3*M_PI/2, 3*M_PI/2-ToRad(angle), 0); CGContextAddArc(ctx, self.frame.size.width/2 , self.frame.size.height/2, radius, 165*M_PI/180, 165*M_PI/180-ToRad(angle1), 0); [_filledColor1 setStroke]; CGContextSetLineWidth(ctx, _lineWidth); CGContextSetLineCap(ctx, kCGLineCapButt); CGContextDrawPath(ctx, kCGPathStroke); CGContextAddArc(ctx, self.frame.size.width/2, self.frame.size.height/2, radius, M_PI/6, M_PI/6-ToRad(angle2), 0); [_filledColor2 setStroke]; CGContextSetLineWidth(ctx, _lineWidth); CGContextSetLineCap(ctx, kCGLineCapButt); CGContextDrawPath(ctx, kCGPathStroke); // } // CGContextDrawPath(ctx, kCGPathStroke); //Add the labels (if necessary) if(labelsEvenSpacing != nil) { [self drawLabels:ctx]; } //The draggable part [self drawHandle:ctx]; } -(void) drawHandle:(CGContextRef)ctx{ CGContextSaveGState(ctx); CGPoint handleCenter = [self pointFromAngle1: angle1]; // if(_handleType == semiTransparentWhiteCircle) { // [[UIColor colorWithWhite:1.0 alpha:0.7] set]; // CGContextFillEllipseInRect(ctx, CGRectMake(handleCenter.x, handleCenter.y, _lineWidth, _lineWidth)); // } else if(_handleType == semiTransparentBlackCircle) { // [[UIColor colorWithWhite:0.0 alpha:0.7] set]; // CGContextFillEllipseInRect(ctx, CGRectMake(handleCenter.x, handleCenter.y, _lineWidth, _lineWidth)); // } else if(_handleType == doubleCircleWithClosedCenter) { // [_handleColor set]; // CGContextAddArc(ctx, handleCenter.x + (_lineWidth)/2, handleCenter.y + (_lineWidth)/2, _lineWidth, 0, M_PI *2, 0); // CGContextSetLineWidth(ctx, 7); // CGContextSetLineCap(ctx, kCGLineCapButt); // CGContextDrawPath(ctx, kCGPathStroke); // CGContextFillEllipseInRect(ctx, CGRectMake(handleCenter.x, handleCenter.y, _lineWidth-1, _lineWidth-1)); // } else if(_handleType == doubleCircleWithOpenCenter) { // [_handleColor set]; // CGContextAddArc(ctx, handleCenter.x + (_lineWidth)/2, handleCenter.y + (_lineWidth)/2, 8, 0, M_PI *2, 0); // CGContextSetLineWidth(ctx, 4); // CGContextSetLineCap(ctx, kCGLineCapButt); // CGContextDrawPath(ctx, kCGPathStroke); // // CGContextAddArc(ctx, handleCenter.x + _lineWidth/2, handleCenter.y + _lineWidth/2, _lineWidth/2, 0, M_PI *2, 0); // CGContextSetLineWidth(ctx, 2); // CGContextSetLineCap(ctx, kCGLineCapButt); // CGContextDrawPath(ctx, kCGPathStroke); // } else if(_handleType == bigCircle) { // [_handleColor set]; // CGContextFillEllipseInRect(ctx, CGRectMake(handleCenter.x-2.5, handleCenter.y-2.5, _lineWidth+5, _lineWidth+5)); // } // [_handleColor set]; // CGContextFillEllipseInRect(ctx, CGRectMake(handleCenter.x-2.5, handleCenter.y-2.5, _lineWidth+5, _lineWidth+5)); // [_handleInColor set]; [_handleColor set]; CGContextAddArc(ctx, handleCenter.x + (_lineWidth)/2, handleCenter.y + (_lineWidth)/2, 8, 0, M_PI *2, 0); CGContextSetLineWidth(ctx, 4); CGContextSetLineCap(ctx, kCGLineCapButt); // CGContextSetShadowWithColor(ctx, CGSizeMake(0, 0), _lineWidth/2, [UIColor blueColor].CGColor); CGContextDrawPath(ctx, kCGPathStroke); CGContextAddArc(ctx, handleCenter.x + _lineWidth/2, handleCenter.y + _lineWidth/2, _lineWidth/2, 0, M_PI *2, 0); [_handleInColor1 set]; // [[UIColor redColor] set]; CGContextSetLineWidth(ctx, 2); CGContextSetLineCap(ctx, kCGLineCapButt); // CGContextSetShadowWithColor(ctx, CGSizeMake(0, 0), _lineWidth, [UIColor blackColor].CGColor); CGContextFillEllipseInRect(ctx, CGRectMake(handleCenter.x-2.5, handleCenter.y-2.5, _lineWidth+5, _lineWidth+5)); // CGContextDrawPath(ctx, kCGPathStroke); CGContextRestoreGState(ctx); CGContextSaveGState(ctx); CGPoint handleCenter2 = [self pointFromAngle2: angle2]; // if(_handleType == semiTransparentWhiteCircle) { // [[UIColor colorWithWhite:1.0 alpha:0.7] set]; // CGContextFillEllipseInRect(ctx, CGRectMake(handleCenter.x, handleCenter.y, _lineWidth, _lineWidth)); // } else if(_handleType == semiTransparentBlackCircle) { // [[UIColor colorWithWhite:0.0 alpha:0.7] set]; // CGContextFillEllipseInRect(ctx, CGRectMake(handleCenter.x, handleCenter.y, _lineWidth, _lineWidth)); // } else if(_handleType == doubleCircleWithClosedCenter) { // [_handleColor set]; // CGContextAddArc(ctx, handleCenter.x + (_lineWidth)/2, handleCenter.y + (_lineWidth)/2, _lineWidth, 0, M_PI *2, 0); // CGContextSetLineWidth(ctx, 7); // CGContextSetLineCap(ctx, kCGLineCapButt); // CGContextDrawPath(ctx, kCGPathStroke); // CGContextFillEllipseInRect(ctx, CGRectMake(handleCenter.x, handleCenter.y, _lineWidth-1, _lineWidth-1)); // } else if(_handleType == doubleCircleWithOpenCenter) { // [_handleColor set]; // CGContextAddArc(ctx, handleCenter.x + (_lineWidth)/2, handleCenter.y + (_lineWidth)/2, 8, 0, M_PI *2, 0); // CGContextSetLineWidth(ctx, 4); // CGContextSetLineCap(ctx, kCGLineCapButt); // CGContextDrawPath(ctx, kCGPathStroke); // // CGContextAddArc(ctx, handleCenter.x + _lineWidth/2, handleCenter.y + _lineWidth/2, _lineWidth/2, 0, M_PI *2, 0); // CGContextSetLineWidth(ctx, 2); // CGContextSetLineCap(ctx, kCGLineCapButt); // CGContextDrawPath(ctx, kCGPathStroke); // } else if(_handleType == bigCircle) { // [_handleColor set]; // CGContextFillEllipseInRect(ctx, CGRectMake(handleCenter.x-2.5, handleCenter.y-2.5, _lineWidth+5, _lineWidth+5)); // } // [_handleColor set]; // CGContextFillEllipseInRect(ctx, CGRectMake(handleCenter2.x-2.5, handleCenter2.y-2.5, _lineWidth+5, _lineWidth+5)); [_handleColor set]; CGContextAddArc(ctx, handleCenter2.x + (_lineWidth)/2, handleCenter2.y + (_lineWidth)/2, 8, 0, M_PI *2, 0); CGContextSetLineWidth(ctx, 4); CGContextSetLineCap(ctx, kCGLineCapButt); // CGContextSetShadowWithColor(ctx, CGSizeMake(0, 0), _lineWidth/2, [UIColor blueColor].CGColor); CGContextDrawPath(ctx, kCGPathStroke); CGContextAddArc(ctx, handleCenter2.x + _lineWidth/2, handleCenter2.y + _lineWidth/2, _lineWidth/2, 0, M_PI *2, 0); [_handleInColor2 set]; // [[UIColor redColor] set]; CGContextSetLineWidth(ctx, 2); CGContextSetLineCap(ctx, kCGLineCapButt); // CGContextSetShadowWithColor(ctx, CGSizeMake(0, 0), _lineWidth, [UIColor blackColor].CGColor); CGContextFillEllipseInRect(ctx, CGRectMake(handleCenter2.x-2.5, handleCenter2.y-2.5, _lineWidth+5, _lineWidth+5)); // CGContextFillEllipseInRect(ctx, CGRectMake(handleCenter2.x-5, handleCenter2.y-5, _lineWidth+10, _lineWidth+10)); // CGContextDrawPath(ctx, kCGPathStroke); CGContextRestoreGState(ctx); // CGContextRestoreGState(ctx); } -(void) drawLabels:(CGContextRef)ctx { if(labelsEvenSpacing == nil || [labelsEvenSpacing count] == 0) { return; } else { NSDictionary *attributes = @{ NSFontAttributeName: _labelFont, NSForegroundColorAttributeName: _labelColor}; int distanceToMove = -15; for (int i=0; i<[labelsEvenSpacing count]; i++) { NSString* label = [labelsEvenSpacing objectAtIndex:[labelsEvenSpacing count] - i - 1]; CGFloat percentageAlongCircle = i/(float)[labelsEvenSpacing count]; CGFloat degreesForLabel = percentageAlongCircle * 360; CGPoint closestPointOnCircleToLabel = [self pointFromAngle1:degreesForLabel]; CGRect labelLocation = CGRectMake(closestPointOnCircleToLabel.x, closestPointOnCircleToLabel.y, [self widthOfString:label withFont:_labelFont], [self heightOfString:label withFont:_labelFont]); CGPoint centerPoint = CGPointMake(self.frame.size.width/2, self.frame.size.height/2); float radiansTowardsCenter = ToRad(AngleFromNorth(centerPoint, closestPointOnCircleToLabel, NO)); labelLocation.origin.x = (labelLocation.origin.x + distanceToMove * cos(radiansTowardsCenter)) - labelLocation.size.width/4; labelLocation.origin.y = (labelLocation.origin.y + distanceToMove * sin(radiansTowardsCenter))- labelLocation.size.height/4; [label drawInRect:labelLocation withAttributes:attributes]; } } } #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]; // } } -(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>=165&¤tAngle<=360)||(currentAngle>=0&¤tAngle<=15)) { angle1 = 360 - (360-165) - currentAngle;//148 }else if(currentAngle>=30&¤tAngle<=150){ angle2=360-(360-30)-currentAngle; } // NSLog(@"%d-angle1-",angle1); // NSLog(@"%d-angle2-",angle2); _currentValue1 = [self valueFromAngle1]; _currentValue2 = [self valueFromAngle2]; [self setNeedsDisplay]; } #pragma mark - helper functions -(CGPoint)pointFromAngle1:(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-(180+15)))) ;//90 result.x = round(centerPoint.x + radius * cos(ToRad(-angleInt-(180+15)))); return result; } -(CGPoint)pointFromAngle2:(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-(360-30)))) ;//90 result.x = round(centerPoint.x + radius * cos(ToRad(-angleInt-(360-30)))); return result; } 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) valueFromAngle1 { if(angle1 <=0) { _currentValue1 = -angle1; } else { _currentValue1 = 15+180+(165-angle1); } fixedAngle = _currentValue1; return (_currentValue1*(_maximumValue - _minimumValue))/210; } -(float) valueFromAngle2 { if(angle2 <0) { _currentValue2 = -angle2; } fixedAngle = _currentValue2; return (_currentValue2*(_maximumValue - _minimumValue))/120; } - (CGFloat) widthOfString:(NSString *)string withFont:(UIFont*)font { NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:font, NSFontAttributeName, nil]; return [[[NSAttributedString alloc] initWithString:string attributes:attributes] size].width; } - (CGFloat) heightOfString:(NSString *)string withFont:(UIFont*)font { NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:font, NSFontAttributeName, nil]; return [[[NSAttributedString alloc] initWithString:string attributes:attributes] size].height; } #pragma mark - public methods -(void)setInnerMarkingLabels:(NSArray*)labels{ labelsEvenSpacing = labels; [self setNeedsDisplay]; } @end
上一篇: 雷神创作大师笔记本评测 挑战3A大作
下一篇: 基于stm32f103c8t6浊度计