Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Visualize 'added value' in a different color #11

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
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 Pod/Classes/MBCircularProgressBarLayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
@property (nonatomic,assign) CGFloat progressAngle;
@property (nonatomic,assign) CGFloat progressRotationAngle;
@property (nonatomic,assign) CGFloat value;
@property (nonatomic,assign) CGFloat addedValue;
@property (nonatomic,assign) CGFloat maxValue;
@property (nonatomic,assign) NSTimeInterval animationDuration;
@property (nonatomic,assign) BOOL animated;
Expand All @@ -26,6 +27,11 @@
@property (nonatomic,strong) UIColor *progressStrokeColor;
@property (nonatomic,assign) CGLineCap progressCapType;

@property (nonatomic,assign) CGFloat additionLineWidth;
@property (nonatomic,strong) UIColor *additionColor;
@property (nonatomic,strong) UIColor *additionStrokeColor;
@property (nonatomic,assign) NSInteger additionCapType;

@property (nonatomic,assign) CGFloat emptyLineWidth;
@property (nonatomic,assign) CGLineCap emptyCapType;
@property (nonatomic,strong) UIColor *emptyLineColor;
Expand Down
56 changes: 50 additions & 6 deletions Pod/Classes/MBCircularProgressBarLayer.m
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,22 @@

@implementation MBCircularProgressBarLayer
@dynamic value;
@dynamic addedValue;
@dynamic maxValue;
@dynamic valueFontSize;
@dynamic unitString;
@dynamic unitFontSize;
@dynamic progressLineWidth;
@dynamic additionLineWidth;
@dynamic progressColor;
@dynamic progressStrokeColor;
@dynamic additionColor;
@dynamic additionStrokeColor;
@dynamic emptyLineWidth;
@dynamic progressAngle;
@dynamic emptyLineColor;
@dynamic emptyCapType;
@dynamic additionCapType;
@dynamic progressCapType;
@dynamic fontColor;
@dynamic progressRotationAngle;
Expand All @@ -45,6 +50,7 @@ - (void) drawInContext:(CGContextRef) context{
CGSize size = CGRectIntegral(CGContextGetClipBoundingBox(context)).size;
[self drawEmptyBar:size context:context];
[self drawProgressBar:size context:context];
[self drawAdditionBar:size context:context];

if (self.showValueString){
[self drawText:size context:context];
Expand Down Expand Up @@ -117,6 +123,42 @@ - (void)drawProgressBar:(CGSize)rectSize context:(CGContextRef)c{
CGPathRelease(strokedArc);
}

- (void)drawAdditionBar:(CGSize)rectSize context:(CGContextRef)c{
if(self.additionLineWidth <= 0){
return;
}

CGMutablePathRef arc = CGPathCreateMutable();

CGPathAddArc(arc, NULL,
rectSize.width/2, rectSize.height/2,
MIN(rectSize.width,rectSize.height)/2 - self.progressLineWidth,
(self.progressAngle/100.f)*M_PI -
((-self.progressRotationAngle/100.f)*2.f+0.5)*M_PI -
(2.f*M_PI)*(self.progressAngle/100.f) * (100.f-100.f*(self.value + self.addedValue)/self.maxValue)/100.f,
(self.progressAngle/100.f)*M_PI -
((-self.progressRotationAngle/100.f)*2.f+0.5)*M_PI -
(2.f*M_PI)*(self.progressAngle/100.f) * (100.f-100.f*self.value/self.maxValue)/100.f,
YES);

CGPathRef strokedArc =
CGPathCreateCopyByStrokingPath(arc, NULL,
self.additionLineWidth,
(CGLineCap)self.additionCapType,
kCGLineJoinMiter,
10);


CGContextAddPath(c, strokedArc);
CGContextSetFillColorWithColor(c, self.additionColor.CGColor);
CGContextSetStrokeColorWithColor(c, self.additionStrokeColor.CGColor);
CGContextDrawPath(c, kCGPathFillStroke);

CGPathRelease(arc);
CGPathRelease(strokedArc);
}


- (void)drawText:(CGSize)rectSize context:(CGContextRef)c
{

Expand All @@ -131,8 +173,10 @@ - (void)drawText:(CGSize)rectSize context:(CGContextRef)c
NSMutableAttributedString *text = [NSMutableAttributedString new];

NSString *formatString = [NSString stringWithFormat:@"%%.%df", (int)self.decimalPlaces];

CGFloat valueToDisplay = self.value + self.addedValue;
NSAttributedString* value =
[[NSAttributedString alloc] initWithString:[NSString stringWithFormat:formatString, self.value] attributes:valueFontAttributes];
[[NSAttributedString alloc] initWithString:[NSString stringWithFormat:formatString, valueToDisplay] attributes:valueFontAttributes];

[text appendAttributedString:value];

Expand Down Expand Up @@ -163,19 +207,19 @@ - (void)drawText:(CGSize)rectSize context:(CGContextRef)c
#pragma mark - Override methods to support animations

+ (BOOL)needsDisplayForKey:(NSString *)key {
if ([key isEqualToString:@"value"]) {
if ([key isEqualToString:@"value"] || [key isEqualToString:@"addedValue"]) {
return YES;
}
return [super needsDisplayForKey:key];
}

- (id<CAAction>)actionForKey:(NSString *)event{
if ([self presentationLayer] != nil) {
if ([event isEqualToString:@"value"] && self.animated) {
if ([self presentationLayer] != nil && self.animated) {
if ([event isEqualToString:@"value"] || [event isEqualToString:@"addedValue"]) {
CABasicAnimation *anim = [CABasicAnimation
animationWithKeyPath:@"value"];
animationWithKeyPath:event];
anim.fromValue = [[self presentationLayer]
valueForKey:@"value"];
valueForKey:event];
anim.duration = self.animationDuration;
return anim;
}
Expand Down
17 changes: 17 additions & 0 deletions Pod/Classes/MBCircularProgressBarView.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ IB_DESIGNABLE
/* The value of the progress bar */
@property (nonatomic,assign) IBInspectable CGFloat value;

/* The added value of the progress bar - the 'delta' section */
@property (nonatomic,assign) IBInspectable CGFloat addedValue;

/* The maximum possible value, used to calculate the progress (value/maxValue) [0,∞) */
@property (nonatomic,assign) IBInspectable CGFloat maxValue;

Expand Down Expand Up @@ -65,6 +68,18 @@ IB_DESIGNABLE
/* The shape of the progress bar cap {kCGLineCapButt=0, kCGLineCapRound=1, kCGLineCapSquare=2} */
@property (nonatomic,assign) IBInspectable NSInteger progressCapType;

/* The width of the current addition bar (user space units) [0,∞) */
@property (nonatomic,assign) IBInspectable CGFloat additionLineWidth;

/* The color of the current addition bar */
@property (nonatomic,strong) IBInspectable UIColor *additionColor;

/* The color of the current addition bar frame */
@property (nonatomic,strong) IBInspectable UIColor *additionStrokeColor;

/* The shape of the current addition bar cap {kCGLineCapButt=0, kCGLineCapRound=1, kCGLineCapSquare=2} */
@property (nonatomic,assign) IBInspectable NSInteger additionCapType;

/* The width of the background bar (user space units) [0,∞) */
@property (nonatomic,assign) IBInspectable CGFloat emptyLineWidth;

Expand All @@ -77,4 +92,6 @@ IB_DESIGNABLE
/* Set the value of the progress bar with animation */
-(void)setValue:(CGFloat)value animateWithDuration:(NSTimeInterval)duration;

/* Set the value of the delta section of the progress bar with animation */
-(void)setAddedValue:(CGFloat)addedValue animateWithDuration:(NSTimeInterval)duration;
@end
51 changes: 51 additions & 0 deletions Pod/Classes/MBCircularProgressBarView.m
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,14 @@ -(void)initView:(CGRect)frame{

[self setUnitString:@"%"];
[self setValue:0.f];
[self setAddedValue:0.f];
[self setMaxValue:100.f];
[self setProgressRotationAngle:0.f];
[self setProgressStrokeColor:[UIColor orangeColor]];
[self setAdditionStrokeColor:[UIColor yellowColor]];
[self setProgressColor:[UIColor orangeColor]];
[self setProgressCapType:kCGLineCapRound];
[self setAdditionCapType:kCGLineCapRound];
[self setEmptyLineColor:[UIColor lightGrayColor]];
[self setFontColor:[UIColor blackColor]];
[self setEmptyLineWidth:1.f];
Expand Down Expand Up @@ -85,6 +88,17 @@ -(void)setValue:(CGFloat)value{
}
}

-(void)setAddedValue:(CGFloat)addedValue{
[self progressLayer].animated = NO;

self.progressLayer.addedValue = addedValue;

//CALayer autogenerated setter using @dynamic doesn't refresh the layer when the value is 0
if(addedValue == 0){
[self.layer setNeedsDisplay];
}
}

-(CGFloat)value{
return self.progressLayer.value;
}
Expand Down Expand Up @@ -118,13 +132,28 @@ -(CGFloat)emptyLineWidth{
return self.progressLayer.emptyLineWidth;
}

-(void)setAdditionLineWidth:(CGFloat)additionLineWidth{
self.progressLayer.additionLineWidth = additionLineWidth;
}

-(CGFloat)additionLineWidth{
return self.progressLayer.additionLineWidth;
}

-(void)setProgressColor:(UIColor*)color{
self.progressLayer.progressColor = color;
}

-(UIColor*)progressColor{
return self.progressLayer.progressColor;
}
-(void)setAdditionColor:(UIColor *)additionColor{
self.progressLayer.additionColor = additionColor;
}

-(UIColor *)additionColor{
return self.progressLayer.additionColor;
}

-(void)setUnitFontSize:(CGFloat)unitFontSize{
self.progressLayer.unitFontSize = unitFontSize;
Expand Down Expand Up @@ -166,6 +195,14 @@ -(UIColor*)progressStrokeColor{
return self.progressLayer.progressStrokeColor;
}

-(void)setAdditionStrokeColor:(UIColor *)additionStrokeColor{
self.progressLayer.additionStrokeColor = additionStrokeColor;
}

-(UIColor *)additionStrokeColor{
return self.progressLayer.additionStrokeColor;
}

-(void)setEmptyLineColor:(UIColor *)emptyLineColor{
self.progressLayer.emptyLineColor = emptyLineColor;
}
Expand Down Expand Up @@ -206,6 +243,14 @@ -(NSInteger)EmptyCapType{
return self.progressLayer.emptyCapType;
}

-(void)setAdditionCapType:(NSInteger)additionCapType{
self.progressLayer.additionCapType = additionCapType;
}

-(NSInteger)additionCapType{
return self.progressLayer.additionCapType;
}

-(CGLineCap)safeCapType:(NSInteger)type{
if(kCGLineCapButt <= type && type <= kCGLineCapSquare){
return (CGLineCap)type;
Expand Down Expand Up @@ -271,4 +316,10 @@ -(void)setValue:(CGFloat)value animateWithDuration:(NSTimeInterval)duration{
[self progressLayer].value = value;
}

-(void)setAddedValue:(CGFloat)addedValue animateWithDuration:(NSTimeInterval)duration{
[self progressLayer].animationDuration = duration;
[self progressLayer].animated = YES;
[self progressLayer].addedValue = addedValue;
}

@end