Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions DACircularProgress/DACircularProgressView.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,17 @@

#import <UIKit/UIKit.h>

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;
Expand Down
42 changes: 32 additions & 10 deletions DACircularProgress/DACircularProgressView.m
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -26,6 +27,7 @@ @implementation DACircularProgressLayer
@dynamic trackTintColor;
@dynamic progressTintColor;
@dynamic roundedCorners;
@dynamic startPosition;
@dynamic thicknessRatio;
@dynamic progress;
@dynamic clockwiseProgress;
Expand All @@ -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);
Expand All @@ -71,22 +75,28 @@ - (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);
CGPathRelease(progressPath);
}

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
};
Expand All @@ -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,
Expand Down Expand Up @@ -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];
Expand Down Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand All @@ -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];
Expand Down