Created
May 15, 2013 12:42
-
-
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.
This file contains 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
// | |
// 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