UIView, UIColor, CGPoint, UIBezierPath, CABasicAnimation
ViewController.h
#import “GMDCircleLoader.h”
@property (weak, nonatomic) IBOutlet UIView *viewActivityIndicator;
ViewController.m
[GMDCircleLoader setOnView:self.viewActivityIndicator withTitle:nil animated:YES];
GMDCircleLoader.h
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
#import <CoreGraphics/CoreGraphics.h>
#pragma mark – Definitions
//———————————-
// To change the color and frame size of the spinner, simply change the color and frame definition here.
//———————————-
#define GMD_SPINNER_COLOR_FRONT [UIColor colorWithRed:235.0/255.0 green:106.0/255.0 blue:63.0/255.0 alpha:1.0]
#define GMD_SPINNER_COLOR_BACK [UIColor colorWithRed:60.0/255.0 green:271.0/255.0 blue:83.0/255.0 alpha:1.0]
#define GMD_SPINNER_FRAME CGRectMake(40.0f, 40.0f, 40.0f, 40.0f)
#define GMD_SPINNER_IMAGE CGRectMake(15, 15,30,30)
#define GMD_IMAGE [UIImage imageNamed:@“image”]
#define GMD_SPINNER_LINE_WIDTH fmaxf(self.frame.size.width * 0.055, 1.f)
#pragma mark – Interface
@interface GMDCircleLoader : UIView
@property (nonatomic, assign) CGFloat lineWidth;
@property (nonatomic, assign) UIColor *lineTintColor;
@property (nonatomic, strong) CAShapeLayer *backgroundLayer, *abackgroundLayer;
@property (nonatomic, assign) BOOL isSpinning;
– (void)start;
– (void)stop;
+ (GMDCircleLoader *)setOnView:(UIView *)view withTitle:(NSString *)title animated:(BOOL)animated;
+ (BOOL)hideFromView:(UIView *)view animated:(BOOL)animated;
@end
GMDCircleLoader.m
@implementation GMDCircleLoader
//———————————–
// Add the loader to view
//———————————–
+ (GMDCircleLoader *)setOnView:(UIView *)view withTitle:(NSString *)title animated:(BOOL)animated {
GMDCircleLoader *hud = [[GMDCircleLoader alloc] initWithFrame:GMD_SPINNER_FRAME];
//You can add an image to the center of the spinner view
// UIImageView *img = [[UIImageView alloc] initWithFrame:GMD_SPINNER_IMAGE];
// img.image = GMD_IMAGE;
// hud.center = img.center;
// [hud addSubview:img];
[hud start];
[view addSubview:hud];
float height = view.frame.size.height;
float width = view.frame.size.width;
CGPoint center = CGPointMake(width/2, height/2);
hud.center = center;
return hud;
}
//————————————
// Hide the leader in view
//————————————
+ (BOOL)hideFromView:(UIView *)view animated:(BOOL)animated {
GMDCircleLoader *hud = [GMDCircleLoader HUDForView:view];
[hud stop];
if (hud) {
[hud removeFromSuperview];
return YES;
}
return NO;
}
//————————————
// Perform search for loader and hide it
//————————————
+ (GMDCircleLoader *)HUDForView: (UIView *)view {
GMDCircleLoader *hud = nil;
NSArray *subViewsArray = view.subviews;
Class hudClass = [GMDCircleLoader class];
for (UIView *aView in subViewsArray) {
if ([aView isKindOfClass:hudClass]) {
hud = (GMDCircleLoader *)aView;
}
}
return hud;
}
#pragma mark – Initialization
– (instancetype)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame])) {
[self setup];
}
return self;
}
#pragma mark – Setup
– (void)setup {
self.backgroundColor = [UIColor clearColor];
//—————————
// Set line width
//—————————
_lineWidth = GMD_SPINNER_LINE_WIDTH;
//—————————
// Round Progress View
//—————————
self.abackgroundLayer = [CAShapeLayer layer];
_abackgroundLayer.strokeColor = GMD_SPINNER_COLOR_BACK.CGColor;
_abackgroundLayer.fillColor = self.backgroundColor.CGColor;
_abackgroundLayer.lineCap = kCALineCapRound;
_abackgroundLayer.lineWidth = _lineWidth;
[self.layer addSublayer:_abackgroundLayer];
self.backgroundLayer = [CAShapeLayer layer];
_backgroundLayer.strokeColor = GMD_SPINNER_COLOR_FRONT.CGColor;
_backgroundLayer.fillColor = self.backgroundColor.CGColor;
_backgroundLayer.lineCap = kCALineCapRound;
_backgroundLayer.lineWidth = _lineWidth;
[self.layer addSublayer:_backgroundLayer];
}
– (void)drawRect:(CGRect)rect {
//————————-
// Make sure layers cover the whole view
//————————-
_backgroundLayer.frame = self.bounds;
}
#pragma mark – Drawing
– (void)drawBackgroundCircle:(BOOL) partial {
CGFloat startAngle = – ((float)M_PI / 2); // 90 Degrees
CGFloat endAngle = (2 * (float)M_PI) + startAngle;
CGPoint center = CGPointMake(self.bounds.size.width/2, self.bounds.size.height/2);
CGFloat radius = (self.bounds.size.width – _lineWidth)/2;
//———————-
// Begin draw background
//———————-
UIBezierPath *processBackgroundPath = [UIBezierPath bezierPath];
processBackgroundPath.lineWidth = _lineWidth;
//—————————————
// Make end angle to 90% of the progress
//—————————————
if (partial) {
endAngle = (1.5f * (float)M_PI) + startAngle;
}
[processBackgroundPath addArcWithCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES];
_backgroundLayer.path = processBackgroundPath.CGPath;
UIBezierPath *aprocessBackgroundPath = [UIBezierPath bezierPath];
aprocessBackgroundPath.lineWidth = _lineWidth;
//—————————————
// Make end angle to 90% of the progress
//—————————————
if (partial) {
endAngle = (2.0f * (float)M_PI) + startAngle;
}
[aprocessBackgroundPath addArcWithCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES];
_abackgroundLayer.path = aprocessBackgroundPath.CGPath;
}
#pragma mark – Spin
– (void)start
{
self.isSpinning = YES;
[self drawBackgroundCircle:YES];
CABasicAnimation *rotationAnimation = [CABasicAnimation animationWithKeyPath:@”transform.rotation.z”];
rotationAnimation.toValue = [NSNumber numberWithFloat:M_PI * 2.0];
rotationAnimation.duration = 1;
rotationAnimation.cumulative = YES;
rotationAnimation.repeatCount = HUGE_VALF;
[_backgroundLayer addAnimation:rotationAnimation forKey:@”rotationAnimation”];
}
– (void)stop{
[self drawBackgroundCircle:NO];
[_backgroundLayer removeAllAnimations];
self.isSpinning = NO;
}
Click here to download Custom Activity Indicator, Circle Activity Indicator Project