From 1a34decc65fb55eaebcc5323d4080c6be4e17262 Mon Sep 17 00:00:00 2001 From: SofteqDG Date: Fri, 5 May 2017 17:58:11 +0300 Subject: [PATCH 1/3] Fix getters for 'emptyCapType' and 'progressRotationAngle' properties --- Pod/Classes/MBCircularProgressBarView.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Pod/Classes/MBCircularProgressBarView.m b/Pod/Classes/MBCircularProgressBarView.m index 5c6c71a..b9c0bf6 100644 --- a/Pod/Classes/MBCircularProgressBarView.m +++ b/Pod/Classes/MBCircularProgressBarView.m @@ -195,7 +195,7 @@ -(void)setProgressRotationAngle:(CGFloat)progressRootationAngle{ self.progressLayer.progressRotationAngle = progressRootationAngle; } --(CGFloat)progressRootationAngle{ +-(CGFloat)progressRotationAngle{ return self.progressLayer.progressRotationAngle; } @@ -211,7 +211,7 @@ -(void)setEmptyCapType:(NSInteger)emptyCapType{ self.progressLayer.emptyCapType = [self safeCapType:emptyCapType]; } --(NSInteger)EmptyCapType{ +-(NSInteger)emptyCapType{ return self.progressLayer.emptyCapType; } From e548555f5ff011bc2ead963bb69e6e80734fa9ee Mon Sep 17 00:00:00 2001 From: SofteqDG Date: Fri, 5 May 2017 18:41:07 +0300 Subject: [PATCH 2/3] New appearance types for progress bar. --- Pod/Classes/MBCircularProgressBarLayer.h | 16 +++++++ Pod/Classes/MBCircularProgressBarLayer.m | 57 +++++++++++++++--------- Pod/Classes/MBCircularProgressBarView.h | 10 +++++ Pod/Classes/MBCircularProgressBarView.m | 40 ++++++++++++++--- 4 files changed, 96 insertions(+), 27 deletions(-) diff --git a/Pod/Classes/MBCircularProgressBarLayer.h b/Pod/Classes/MBCircularProgressBarLayer.h index 561a9c1..3465f00 100644 --- a/Pod/Classes/MBCircularProgressBarLayer.h +++ b/Pod/Classes/MBCircularProgressBarLayer.h @@ -8,6 +8,12 @@ @import QuartzCore; +typedef NS_ENUM(NSInteger, MBCircularProgressBarAppearanceType) { + MBCircularProgressBarAppearanceTypeOverlaysEmptyLine = 0, + MBCircularProgressBarAppearanceTypeAboveEmptyLine = 1, + MBCircularProgressBarAppearanceTypeUnderEmptyLine = 2 +}; + /** * The MBCircularProgressBarLayer class is a CALayer subclass that represents the underlying layer * of MBCircularProgressBarView. @@ -24,6 +30,11 @@ */ @property (nonatomic,assign) CGFloat progressRotationAngle; +/** + * Progress bar appearance type + */ +@property (nonatomic,assign) MBCircularProgressBarAppearanceType progressAppearanceType; + /** * The value of the progress bar */ @@ -34,6 +45,11 @@ */ @property (nonatomic,assign) CGFloat maxValue; +/** + * Padding from borders + */ +@property (nonatomic,assign) CGFloat borderPadding; + /** * Animation duration in seconds */ diff --git a/Pod/Classes/MBCircularProgressBarLayer.m b/Pod/Classes/MBCircularProgressBarLayer.m index 9e73d56..0b1718a 100644 --- a/Pod/Classes/MBCircularProgressBarLayer.m +++ b/Pod/Classes/MBCircularProgressBarLayer.m @@ -14,6 +14,7 @@ @implementation MBCircularProgressBarLayer @dynamic value; @dynamic maxValue; +@dynamic borderPadding; @dynamic valueFontSize; @dynamic unitString; @dynamic unitFontSize; @@ -28,6 +29,7 @@ @implementation MBCircularProgressBarLayer @dynamic progressCapType; @dynamic fontColor; @dynamic progressRotationAngle; +@dynamic progressAppearanceType; @dynamic decimalPlaces; @dynamic valueDecimalFontSize; @dynamic unitFontName; @@ -48,28 +50,38 @@ - (void) drawInContext:(CGContextRef) context{ UIGraphicsPushContext(context); - CGSize size = CGRectIntegral(CGContextGetClipBoundingBox(context)).size; - [self drawEmptyBar:size context:context]; - [self drawProgressBar:size context:context]; + CGRect rect = CGContextGetClipBoundingBox(context); + rect = CGRectIntegral(CGRectInset(rect, self.borderPadding, self.borderPadding)); + + [self drawEmptyBar:rect context:context]; + [self drawProgressBar:rect context:context]; if (self.showValueString){ - [self drawText:size context:context]; + [self drawText:rect context:context]; } UIGraphicsPopContext(); } -- (void)drawEmptyBar:(CGSize)rectSize context:(CGContextRef)c{ +- (void)drawEmptyBar:(CGRect)rect context:(CGContextRef)c{ if(self.emptyLineWidth <= 0){ return; } - CGMutablePathRef arc = CGPathCreateMutable(); + CGPoint center = {CGRectGetMidX(rect), CGRectGetMidY(rect)}; + CGFloat radius = MIN(CGRectGetWidth(rect), CGRectGetHeight(rect))/2; + if (self.progressAppearanceType == MBCircularProgressBarAppearanceTypeOverlaysEmptyLine) { + radius = radius - MAX(self.emptyLineWidth, self.progressLineWidth)/2.f; + } else if (self.progressAppearanceType == MBCircularProgressBarAppearanceTypeAboveEmptyLine) { + radius = radius - self.progressLineWidth - self.emptyLineWidth/2.f; + } else { + radius = radius - self.emptyLineWidth/2.f; + } + CGMutablePathRef arc = CGPathCreateMutable(); CGPathAddArc(arc, NULL, - rectSize.width/2, rectSize.height/2, - MIN(rectSize.width,rectSize.height)/2 - self.progressLineWidth, + center.x, center.y, radius, (self.progressAngle/100.f)*M_PI-((-self.progressRotationAngle/100.f)*2.f+0.5)*M_PI, -(self.progressAngle/100.f)*M_PI-((-self.progressRotationAngle/100.f)*2.f+0.5)*M_PI, YES); @@ -92,16 +104,24 @@ - (void)drawEmptyBar:(CGSize)rectSize context:(CGContextRef)c{ CGPathRelease(strokedArc); } -- (void)drawProgressBar:(CGSize)rectSize context:(CGContextRef)c{ +- (void)drawProgressBar:(CGRect)rect context:(CGContextRef)c{ if(self.progressLineWidth <= 0){ return; } - CGMutablePathRef arc = CGPathCreateMutable(); + CGPoint center = {CGRectGetMidX(rect), CGRectGetMidY(rect)}; + CGFloat radius = MIN(CGRectGetWidth(rect), CGRectGetHeight(rect))/2; + if (self.progressAppearanceType == MBCircularProgressBarAppearanceTypeOverlaysEmptyLine) { + radius = radius - MAX(self.emptyLineWidth, self.progressLineWidth)/2.f; + } else if (self.progressAppearanceType == MBCircularProgressBarAppearanceTypeAboveEmptyLine) { + radius = radius - self.progressLineWidth/2.f; + } else { + radius = radius - self.emptyLineWidth - self.progressLineWidth/2.f; + } + CGMutablePathRef arc = CGPathCreateMutable(); CGPathAddArc(arc, NULL, - rectSize.width/2, rectSize.height/2, - MIN(rectSize.width,rectSize.height)/2 - self.progressLineWidth, + center.x, center.y, radius, (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, -(self.progressAngle/100.f)*M_PI-((-self.progressRotationAngle/100.f)*2.f+0.5)*M_PI, YES); @@ -123,14 +143,11 @@ - (void)drawProgressBar:(CGSize)rectSize context:(CGContextRef)c{ CGPathRelease(strokedArc); } -- (void)drawText:(CGSize)rectSize context:(CGContextRef)c -{ - - +- (void)drawText:(CGRect)rect context:(CGContextRef)c{ NSMutableParagraphStyle* textStyle = NSMutableParagraphStyle.defaultParagraphStyle.mutableCopy; textStyle.alignment = NSTextAlignmentLeft; - CGFloat valueFontSize = self.valueFontSize == -1 ? rectSize.height/5 : self.valueFontSize; + CGFloat valueFontSize = self.valueFontSize == -1 ? CGRectGetHeight(rect)/5 : self.valueFontSize; NSDictionary* valueFontAttributes = @{NSFontAttributeName: [UIFont fontWithName: self.valueFontName size:valueFontSize], NSForegroundColorAttributeName: self.fontColor, NSParagraphStyleAttributeName: textStyle}; @@ -158,7 +175,7 @@ - (void)drawText:(CGSize)rectSize context:(CGContextRef)c // ad the unit only if specified if (self.showUnitString) { - NSDictionary* unitFontAttributes = @{NSFontAttributeName: [UIFont fontWithName: self.unitFontName size:self.unitFontSize == -1 ? rectSize.height/7 : self.unitFontSize], NSForegroundColorAttributeName: self.fontColor, NSParagraphStyleAttributeName: textStyle}; + NSDictionary* unitFontAttributes = @{NSFontAttributeName: [UIFont fontWithName: self.unitFontName size:self.unitFontSize == -1 ? CGRectGetHeight(rect)/7 : self.unitFontSize], NSForegroundColorAttributeName: self.fontColor, NSParagraphStyleAttributeName: textStyle}; NSAttributedString* unit = [[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@", self.unitString] attributes:unitFontAttributes]; @@ -167,8 +184,8 @@ - (void)drawText:(CGSize)rectSize context:(CGContextRef)c CGSize percentSize = [text size]; CGPoint textCenter = CGPointMake( - rectSize.width/2-percentSize.width/2 + self.textOffset.x, - rectSize.height/2-percentSize.height/2 + self.textOffset.y + CGRectGetMidX(rect)-percentSize.width/2 + self.textOffset.x, + CGRectGetMidY(rect)-percentSize.height/2 + self.textOffset.y ); [text drawAtPoint:textCenter]; diff --git a/Pod/Classes/MBCircularProgressBarView.h b/Pod/Classes/MBCircularProgressBarView.h index 0eb5fab..425de6f 100644 --- a/Pod/Classes/MBCircularProgressBarView.h +++ b/Pod/Classes/MBCircularProgressBarView.h @@ -30,6 +30,11 @@ IB_DESIGNABLE */ @property (nonatomic,assign) IBInspectable CGFloat maxValue; +/** + * Padding from borders + */ +@property (nonatomic,assign) IBInspectable CGFloat borderPadding; + /* * Number of decimal places of the value [0,∞) */ @@ -75,6 +80,11 @@ IB_DESIGNABLE */ @property (nonatomic,strong) IBInspectable UIColor *fontColor; +/** + * Progress bar appearance type + */ +@property (nonatomic,assign) IBInspectable NSInteger progressAppearanceType; + /** * Progress bar rotation (Clockewise) [0,100] */ diff --git a/Pod/Classes/MBCircularProgressBarView.m b/Pod/Classes/MBCircularProgressBarView.m index b9c0bf6..8fecc39 100644 --- a/Pod/Classes/MBCircularProgressBarView.m +++ b/Pod/Classes/MBCircularProgressBarView.m @@ -11,8 +11,7 @@ @implementation MBCircularProgressBarView -- (instancetype)initWithCoder:(NSCoder *)coder -{ +-(instancetype)initWithCoder:(NSCoder *)coder{ self = [super initWithCoder:coder]; if (self) { [self initView:[self frame]]; @@ -28,8 +27,7 @@ -(instancetype)init{ return self; } -- (instancetype)initWithFrame:(CGRect)frame -{ +-(instancetype)initWithFrame:(CGRect)frame{ self = [super initWithFrame:frame]; if (self) { [self initView:frame]; @@ -40,10 +38,15 @@ - (instancetype)initWithFrame:(CGRect)frame -(void)initView:(CGRect)frame{ //Without setting the content scale factor the layer would be pixelated [self setContentScaleFactor:[[UIScreen mainScreen] scale]]; - + + //This mode forces redrawing when bounds change (e.g. bounds change in animation) + [self setContentMode:UIViewContentModeRedraw]; + [self setUnitString:@"%"]; [self setValue:0.f]; [self setMaxValue:100.f]; + [self setBorderPadding:1.f]; + [self setProgressAppearanceType:0]; [self setProgressRotationAngle:0.f]; [self setProgressStrokeColor:[UIColor orangeColor]]; [self setProgressColor:[UIColor orangeColor]]; @@ -103,6 +106,14 @@ -(CGFloat)maxValue{ return self.progressLayer.maxValue; } +-(void)setBorderPadding:(CGFloat)borderPadding{ + self.progressLayer.borderPadding = borderPadding; +} + +-(CGFloat)borderPadding{ + return self.progressLayer.borderPadding; +} + -(void)setProgressLineWidth:(CGFloat)width{ self.progressLayer.progressLineWidth = width; } @@ -191,6 +202,22 @@ -(CGFloat)progressAngle{ return self.progressLayer.progressAngle; } +-(void)setProgressAppearanceType:(NSInteger)progressAppearanceType{ + self.progressLayer.progressAppearanceType = [self safeProgressAppearanceType:progressAppearanceType]; +} + +-(NSInteger)progressAppearanceType{ + return self.progressLayer.progressAppearanceType; +} + +-(MBCircularProgressBarAppearanceType)safeProgressAppearanceType:(NSInteger)progressAppearanceType{ + if(MBCircularProgressBarAppearanceTypeOverlaysEmptyLine <= progressAppearanceType && progressAppearanceType <= MBCircularProgressBarAppearanceTypeUnderEmptyLine){ + return (MBCircularProgressBarAppearanceType)progressAppearanceType; + } + + return MBCircularProgressBarAppearanceTypeOverlaysEmptyLine; +} + -(void)setProgressRotationAngle:(CGFloat)progressRootationAngle{ self.progressLayer.progressRotationAngle = progressRootationAngle; } @@ -285,8 +312,7 @@ -(MBCircularProgressBarLayer*)progressLayer{ return layer; } -+ (Class) layerClass -{ ++ (Class) layerClass { return [MBCircularProgressBarLayer class]; } From f97c1ac06c4b2d3708ad0675bc11bfc5f64905a3 Mon Sep 17 00:00:00 2001 From: SofteqDG Date: Fri, 5 May 2017 19:10:15 +0300 Subject: [PATCH 3/3] Fix travis build --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index ef30b0e..ffcedf0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ language: objective-c cache: cocoapods -osx_image: xcode8.1 +osx_image: xcode8.3 # podfile: Example/Podfile rvm: @@ -15,5 +15,5 @@ before_install: install: - gem install xcpretty --no-rdoc --no-ri --no-document --quiet script: -- set -o pipefail && xcodebuild test -workspace Example/MBCircularProgressBar.xcworkspace -scheme MBCircularProgressBar-Example -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO | xcpretty -c +- set -o pipefail && xcodebuild clean test -workspace Example/MBCircularProgressBar.xcworkspace -scheme MBCircularProgressBar-Example -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 6s' | xcpretty -c - pod lib lint --quick