From 97d4f168611b31a9f92952cc472bf08fff128f45 Mon Sep 17 00:00:00 2001 From: Oleksii Kuchma Date: Thu, 18 Sep 2014 02:58:56 +0300 Subject: [PATCH] Add startPosition property --- DACircularProgress/DACircularProgressView.h | 6 +++ DACircularProgress/DACircularProgressView.m | 42 ++++++++++++++----- .../ViewController.m | 2 + 3 files changed, 40 insertions(+), 10 deletions(-) diff --git a/DACircularProgress/DACircularProgressView.h b/DACircularProgress/DACircularProgressView.h index 9169c53..9b3be04 100644 --- a/DACircularProgress/DACircularProgressView.h +++ b/DACircularProgress/DACircularProgressView.h @@ -8,11 +8,17 @@ #import +static CGFloat DACircularStartPositionRight = 0.f; +static CGFloat DACircularStartPositionTop = M_PI_2; +static CGFloat DACircularStartPositionLeft = M_PI; +static CGFloat DACircularStartPositionBottom = M_PI + M_PI_2; + @interface DACircularProgressView : UIView @property(nonatomic, strong) UIColor *trackTintColor UI_APPEARANCE_SELECTOR; @property(nonatomic, strong) UIColor *progressTintColor UI_APPEARANCE_SELECTOR; @property(nonatomic) NSInteger roundedCorners UI_APPEARANCE_SELECTOR; // Can not use BOOL with UI_APPEARANCE_SELECTOR :-( +@property(nonatomic) CGFloat startPosition UI_APPEARANCE_SELECTOR; @property(nonatomic) CGFloat thicknessRatio UI_APPEARANCE_SELECTOR; @property(nonatomic) NSInteger clockwiseProgress UI_APPEARANCE_SELECTOR; // Can not use BOOL with UI_APPEARANCE_SELECTOR :-( @property(nonatomic) CGFloat progress; diff --git a/DACircularProgress/DACircularProgressView.m b/DACircularProgress/DACircularProgressView.m index 540f004..d23e033 100644 --- a/DACircularProgress/DACircularProgressView.m +++ b/DACircularProgress/DACircularProgressView.m @@ -15,6 +15,7 @@ @interface DACircularProgressLayer : CALayer @property(nonatomic, strong) UIColor *trackTintColor; @property(nonatomic, strong) UIColor *progressTintColor; @property(nonatomic) NSInteger roundedCorners; +@property(nonatomic) CGFloat startPosition; @property(nonatomic) CGFloat thicknessRatio; @property(nonatomic) CGFloat progress; @property(nonatomic) NSInteger clockwiseProgress; @@ -26,6 +27,7 @@ @implementation DACircularProgressLayer @dynamic trackTintColor; @dynamic progressTintColor; @dynamic roundedCorners; +@dynamic startPosition; @dynamic thicknessRatio; @dynamic progress; @dynamic clockwiseProgress; @@ -45,17 +47,19 @@ - (void)drawInContext:(CGContextRef)context CGPoint centerPoint = CGPointMake(rect.size.width / 2.0f, rect.size.height / 2.0f); CGFloat radius = MIN(rect.size.height, rect.size.width) / 2.0f; + CGFloat thicknessRatio = self.thicknessRatio; BOOL clockwise = (self.clockwiseProgress != 0); CGFloat progress = MIN(self.progress, 1.0f - FLT_EPSILON); + CGFloat startRadians = -self.startPosition; CGFloat radians = 0; if (clockwise) { - radians = (float)((progress * 2.0f * M_PI) - M_PI_2); + radians = (float)(startRadians + (progress * 2 * M_PI)); } else { - radians = (float)(3 * M_PI_2 - (progress * 2.0f * M_PI)); + radians = (float)(startRadians - (progress * 2 * M_PI)); } CGContextSetFillColorWithColor(context, self.trackTintColor.CGColor); @@ -71,7 +75,7 @@ - (void)drawInContext:(CGContextRef)context CGContextSetFillColorWithColor(context, self.progressTintColor.CGColor); CGMutablePathRef progressPath = CGPathCreateMutable(); CGPathMoveToPoint(progressPath, NULL, centerPoint.x, centerPoint.y); - CGPathAddArc(progressPath, NULL, centerPoint.x, centerPoint.y, radius, (float)(3.0f * M_PI_2), radians, !clockwise); + CGPathAddArc(progressPath, NULL, centerPoint.x, centerPoint.y, radius, startRadians, radians, !clockwise); CGPathCloseSubpath(progressPath); CGContextAddPath(context, progressPath); CGContextFillPath(context); @@ -79,14 +83,20 @@ - (void)drawInContext:(CGContextRef)context } if (progress > 0.0f && self.roundedCorners) { - CGFloat pathWidth = radius * self.thicknessRatio; - CGFloat xOffset = radius * (1.0f + ((1.0f - (self.thicknessRatio / 2.0f)) * cosf(radians))); - CGFloat yOffset = radius * (1.0f + ((1.0f - (self.thicknessRatio / 2.0f)) * sinf(radians))); - CGPoint endPoint = CGPointMake(xOffset, yOffset); + CGFloat pathWidth = radius * thicknessRatio; + CGFloat tmp = 1.0f - (thicknessRatio / 2.0f); + + CGFloat startXOffset = radius * (1.0f + (tmp * cosf(startRadians))); + CGFloat startYOffset = radius * (1.0f + (tmp * sinf(startRadians))); + CGPoint startPoint = CGPointMake(startXOffset, startYOffset); + + CGFloat endXOffset = radius * (1.0f + (tmp * cosf(radians))); + CGFloat endYOffset = radius * (1.0f + (tmp * sinf(radians))); + CGPoint endPoint = CGPointMake(endXOffset, endYOffset); CGRect startEllipseRect = (CGRect) { - .origin.x = centerPoint.x - pathWidth / 2.0f, - .origin.y = 0.0f, + .origin.x = startPoint.x - pathWidth / 2.0f, + .origin.y = startPoint.y - pathWidth / 2.0f, .size.width = pathWidth, .size.height = pathWidth }; @@ -104,7 +114,7 @@ - (void)drawInContext:(CGContextRef)context } CGContextSetBlendMode(context, kCGBlendModeClear); - CGFloat innerRadius = radius * (1.0f - self.thicknessRatio); + CGFloat innerRadius = radius * (1.0f - thicknessRatio); CGRect clearRect = (CGRect) { .origin.x = centerPoint.x - innerRadius, .origin.y = centerPoint.y - innerRadius, @@ -133,6 +143,7 @@ + (void) initialize [circularProgressViewAppearance setThicknessRatio:0.3f]; [circularProgressViewAppearance setRoundedCorners:NO]; [circularProgressViewAppearance setClockwiseProgress:YES]; + [circularProgressViewAppearance setStartPosition:DACircularStartPositionTop]; [circularProgressViewAppearance setIndeterminateDuration:2.0f]; [circularProgressViewAppearance setIndeterminate:NO]; @@ -243,6 +254,17 @@ - (void)setRoundedCorners:(NSInteger)roundedCorners [self.circularProgressLayer setNeedsDisplay]; } +- (CGFloat)startPosition +{ + return self.circularProgressLayer.startPosition; +} + +- (void)setStartPosition:(CGFloat)startPosition +{ + self.circularProgressLayer.startPosition = startPosition; + [self.circularProgressLayer setNeedsDisplay]; +} + - (CGFloat)thicknessRatio { return self.circularProgressLayer.thicknessRatio; diff --git a/DACircularProgressExample/DACircularProgressExample/ViewController.m b/DACircularProgressExample/DACircularProgressExample/ViewController.m index 09b3892..05e6c67 100644 --- a/DACircularProgressExample/DACircularProgressExample/ViewController.m +++ b/DACircularProgressExample/DACircularProgressExample/ViewController.m @@ -40,6 +40,7 @@ - (void)viewDidLoad self.largestProgressView.progressTintColor = [UIColor yellowColor]; self.largestProgressView.thicknessRatio = 1.0f; self.largestProgressView.clockwiseProgress = NO; + self.largestProgressView.startPosition = DACircularStartPositionLeft; // Labeled progress views self.labeledProgressView = [[DALabeledCircularProgressView alloc] @@ -48,6 +49,7 @@ - (void)viewDidLoad [self.view addSubview:self.labeledProgressView]; self.labeledLargeProgressView.roundedCorners = NO; + self.labeledLargeProgressView.startPosition = DACircularStartPositionBottom; [self.view addSubview:self.labeledLargeProgressView]; [self startAnimation];