Examples:
Created
February 5, 2012 16:48
-
-
Save zwaldowski/1746530 to your computer and use it in GitHub Desktop.
Layer-backed pie progress view
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@interface DZRoundProgressView : UIView | |
@property (nonatomic) CGFloat progress; | |
- (void)setProgress:(CGFloat)progress animated:(BOOL)animated; | |
@end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "DZRoundProgressView.h" | |
#import <QuartzCore/QuartzCore.h> | |
@interface DZRoundProgressLayer : CALayer | |
@property (nonatomic) CGFloat progress; | |
@end | |
@implementation DZRoundProgressLayer | |
// Using Core Animation's generated properties allows | |
// it to do tweening for us. | |
@dynamic progress; | |
// This is the core of what does animation for us. It | |
// tells CoreAnimation that it needs to redisplay on | |
// each new value of progress, including tweened ones. | |
+ (BOOL)needsDisplayForKey:(NSString *)key { | |
return [key isEqualToString:@"progress"] || [super needsDisplayForKey:key]; | |
} | |
// This is the other crucial half to tweening. | |
// The animation we return is compatible with that | |
// used by UIView, but it also enables implicit | |
// filling-up-the-pie animations. | |
- (id)actionForKey:(NSString *) aKey { | |
if ([aKey isEqualToString:@"progress"]) { | |
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:aKey]; | |
animation.fromValue = [self.presentationLayer valueForKey:aKey]; | |
return animation; | |
} | |
return [super actionForKey:aKey]; | |
} | |
// This is the gold; the drawing of the pie itself. | |
// In this code, it draws in a "HUD"-y style, using | |
// the same color to fill as the border. | |
- (void)drawInContext:(CGContextRef)context { | |
CGRect circleRect = self.bounds; | |
CGFloat radius = CGRectGetMidX(circleRect); | |
CGPoint center = CGPointMake(radius, CGRectGetMidY(circleRect)); | |
CGFloat startAngle = -M_PI / 2; | |
CGFloat endAngle = self.progress * 2 * M_PI + startAngle; | |
CGContextSetFillColorWithColor(context, self.borderColor); | |
CGContextMoveToPoint(context, center.x, center.y); | |
CGContextAddArc(context, center.x, center.y, radius, startAngle, endAngle, 0); | |
CGContextClosePath(context); | |
CGContextFillPath(context); | |
[super drawInContext:context]; | |
} | |
@end | |
@implementation DZRoundProgressView | |
+ (Class)layerClass { | |
return [DZRoundProgressLayer class]; | |
} | |
- (id)init { | |
return [self initWithFrame:CGRectMake(0.0f, 0.0f, 37.0f, 37.0f)]; | |
} | |
- (id)initWithFrame:(CGRect)frame { | |
if ((self = [super initWithFrame:frame])) { | |
self.opaque = NO; | |
self.backgroundColor = [UIColor clearColor]; | |
self.layer.borderWidth = 2.0f; | |
self.layer.borderColor = [[UIColor whiteColor] CGColor]; | |
self.layer.cornerRadius = CGRectGetMidX(frame); | |
self.layer.backgroundColor = [[UIColor colorWithWhite:1.0 alpha:0.15] CGColor]; | |
} | |
return self; | |
} | |
- (void)setProgress:(CGFloat)progress { | |
[self setProgress:progress animated:NO]; | |
} | |
// The method that actually sets the progress on the layer. | |
// Even if you're incrementing (with or without animation) | |
// for every .01 of the pie, each animation cancels out the | |
// previous one. | |
- (void)setProgress:(CGFloat)progress animated:(BOOL)animated { | |
NSTimeInterval length = animated ? (1./3.) : 0.0; | |
[UIView animateWithDuration:length delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{ | |
[(DZRoundProgressLayer *)self.layer setProgress:progress]; | |
} completion:NULL]; | |
} | |
- (CGFloat)progress { | |
return [(DZRoundProgressLayer *)self.layer progress]; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment