Skip to content

Instantly share code, notes, and snippets.

@tyrone-sudeium
Created May 15, 2013 12:42
Show Gist options
  • Save tyrone-sudeium/5583727 to your computer and use it in GitHub Desktop.
Save tyrone-sudeium/5583727 to your computer and use it in GitHub Desktop.
A spinning disabled overlay, akin to ones you'd find on action bars in MMOs.
//
// SDTimedDisableOverlayView.m
// TimedDisabledAnimation
//
// Created by Tyrone Trevorrow on 15-05-13.
// Copyright (c) 2013 Sudeium. All rights reserved.
//
#import "SDTimedDisableOverlayView.h"
static const NSTimeInterval kTargetFramerate = 1.0/60.0;
@interface SDTimedDisableOverlayView ()
@property (nonatomic, strong) NSTimer *timer;
@property (nonatomic, copy) void(^animationCompletion)(BOOL);
@end
@implementation SDTimedDisableOverlayView {
double _currentAngle;
double _deltaAnglePerTick;
}
- (UIBezierPath*) disabledAreaPath
{
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect: self.bounds
cornerRadius: self.bounds.size.height / 2];
return path;
}
- (void) beginAnimationWithCompletion:(CGFloat)completion duration:(NSTimeInterval)duration completionHandler:(void (^)(BOOL))completionHandler
{
if (self.animationCompletion != NULL) {
self.animationCompletion(NO);
}
self.animationCompletion = completionHandler;
_currentAngle = completion * M_PI * 2;
double angleToCover = (M_PI * 2) - _currentAngle;
_deltaAnglePerTick = angleToCover / duration * kTargetFramerate;
if (self.timer != nil) {
[self.timer invalidate];
}
self.timer = [NSTimer timerWithTimeInterval: kTargetFramerate
target: self
selector: @selector(_tick)
userInfo: nil
repeats: YES];
[[NSRunLoop currentRunLoop] addTimer: self.timer
forMode: NSRunLoopCommonModes];
}
- (void) _tick
{
_currentAngle += _deltaAnglePerTick;
if (_currentAngle >= 2*M_PI) {
[self.timer invalidate];
self.timer = nil;
if (self.animationCompletion != NULL) {
self.animationCompletion(YES);
}
}
[self setNeedsDisplay];
}
- (void)drawRect:(CGRect)rect
{
UIBezierPath *shape = [self disabledAreaPath];
[[UIColor colorWithWhite: 0 alpha: 0.5] set];
[shape fill];
CGFloat radius = rect.size.height / 2.0;
if (rect.size.width > rect.size.height) {
radius = rect.size.width / 2.0;
}
CGPoint center = CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect));
UIBezierPath *cutOut = [UIBezierPath new];
[cutOut moveToPoint: center];
[cutOut addLineToPoint: CGPointMake(center.x, center.y - radius)];
[cutOut addArcWithCenter: center radius: radius startAngle: -M_PI_2 endAngle: (_currentAngle - M_PI_2) clockwise: YES];
[cutOut addLineToPoint: center];
[[UIColor whiteColor] set];
[cutOut fillWithBlendMode: kCGBlendModeClear alpha: 1];
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment