From bcb88f5637a29a6e06224fa7f26b619d76703a76 Mon Sep 17 00:00:00 2001 From: John Pope Date: Tue, 3 Dec 2013 18:00:49 +1100 Subject: [PATCH 1/6] add animation timing animate / tween progress --- .../External/PRTween/lib/PRTween.h | 443 +++++++ .../External/PRTween/lib/PRTween.m | 1175 +++++++++++++++++ .../PRTween/lib/PRTweenTimingFunctions.h | 82 ++ .../PRTween/lib/PRTweenTimingFunctions.m | 230 ++++ KACircleProgressView/KAAppDelegate.m | 12 +- KACircleProgressView/KAViewController.h | 10 +- KACircleProgressView/KAViewController.m | 99 +- 7 files changed, 2036 insertions(+), 15 deletions(-) create mode 100755 KACircleProgressView/External/PRTween/lib/PRTween.h create mode 100755 KACircleProgressView/External/PRTween/lib/PRTween.m create mode 100755 KACircleProgressView/External/PRTween/lib/PRTweenTimingFunctions.h create mode 100755 KACircleProgressView/External/PRTween/lib/PRTweenTimingFunctions.m mode change 100644 => 100755 KACircleProgressView/KAAppDelegate.m mode change 100644 => 100755 KACircleProgressView/KAViewController.h mode change 100644 => 100755 KACircleProgressView/KAViewController.m diff --git a/KACircleProgressView/External/PRTween/lib/PRTween.h b/KACircleProgressView/External/PRTween/lib/PRTween.h new file mode 100755 index 0000000..2f367ef --- /dev/null +++ b/KACircleProgressView/External/PRTween/lib/PRTween.h @@ -0,0 +1,443 @@ +#import +#import "PRTweenTimingFunctions.h" + +typedef CGFloat(*PRTweenTimingFunction)(CGFloat, CGFloat, CGFloat, CGFloat); + +#if NS_BLOCKS_AVAILABLE +@class PRTweenPeriod; + +typedef void (^PRTweenUpdateBlock)(PRTweenPeriod *period); + +typedef void (^PRTweenCompleteBlock)(BOOL finished); + +#endif + +enum { + PRTweenHasTweenedValueObserver = 1 << 0, + PRTweenHasTweenedLerpObserver = 1 << 1, +}; +typedef NSUInteger PRTweenHasTweenedObserverOptions; + +@interface PRTweenPeriod : NSObject { + CGFloat duration; + CGFloat delay; + CGFloat startOffset; + CGFloat startValue; + CGFloat endValue; + CGFloat tweenedValue; +} + +@property(nonatomic) CGFloat startValue; +@property(nonatomic) CGFloat endValue; +@property(nonatomic) CGFloat tweenedValue; +@property(nonatomic) CGFloat duration; +@property(nonatomic) CGFloat delay; +@property(nonatomic) CGFloat startOffset; + ++ (id)periodWithStartValue:(CGFloat)aStartValue + endValue:(CGFloat)anEndValue + duration:(CGFloat)duration; + ++ (id)periodWithStartValue:(CGFloat)aStartValue + endValue:(CGFloat)anEndValue + duration:(CGFloat)duration + delay:(CGFloat)delay; + +@end + +@protocol PRTweenLerpPeriod + +- (NSValue *)tweenedValueForProgress:(CGFloat)progress; + +- (void)setProgress:(CGFloat)progress; + +@end + +@interface PRTweenLerpPeriod : PRTweenPeriod { + NSValue *startLerp; + NSValue *endLerp; + NSValue *tweenedLerp; +} + +@property(nonatomic, copy) NSValue *startLerp; +@property(nonatomic, copy) NSValue *endLerp; +@property(nonatomic, copy) NSValue *tweenedLerp; + ++ (id)periodWithStartValue:(NSValue *)aStartValue + endValue:(NSValue *)anEndValue + duration:(CGFloat)duration; + ++ (id)periodWithStartValue:(NSValue *)aStartValue + endValue:(NSValue *)anEndValue + duration:(CGFloat)duration + delay:(CGFloat)delay; +@end + +@interface PRTweenCGPointLerpPeriod : PRTweenLerpPeriod ++ (id)periodWithStartCGPoint:(CGPoint)aStartPoint + endCGPoint:(CGPoint)anEndPoint + duration:(CGFloat)duration; + +- (CGPoint)startCGPoint; + +- (CGPoint)tweenedCGPoint; + +- (CGPoint)endCGPoint; +@end + +@interface PRTweenCGRectLerpPeriod : PRTweenLerpPeriod ++ (id)periodWithStartCGRect:(CGRect)aStartRect + endCGRect:(CGRect)anEndRect + duration:(CGFloat)duration; + +- (CGRect)startCGRect; + +- (CGRect)tweenedCGRect; + +- (CGRect)endCGRect; +@end + +@interface PRTweenCGSizeLerpPeriod : PRTweenLerpPeriod ++ (id)periodWithStartCGSize:(CGSize)aStartSize + endCGSize:(CGSize)anEndSize + duration:(CGFloat)duration; + ++ (id)periodWithStartCGSize:(CGSize)aStartSize + endCGSize:(CGSize)anEndSize + duration:(CGFloat)duration + delay:(CGFloat)delay; + +- (CGSize)startCGSize; + +- (CGSize)tweenedCGSize; + +- (CGSize)endCGSize; +@end + +@interface PRTweenOperation : NSObject { + PRTweenPeriod *period; + NSObject *target; + SEL updateSelector; + SEL completeSelector; + PRTweenTimingFunction timingFunction; + + CGFloat *boundRef; + SEL boundGetter; + SEL boundSetter; + + BOOL override; + BOOL wasPreempted; + + PRTweenHasTweenedObserverOptions observers; + +#if NS_BLOCKS_AVAILABLE + PRTweenUpdateBlock updateBlock; + PRTweenCompleteBlock completeBlock; +#endif + +@private + BOOL canUseBuiltAnimation; +} + +@property(nonatomic, retain) PRTweenPeriod *period; +@property(nonatomic, retain) NSObject *target; +@property(nonatomic) SEL updateSelector; +@property(nonatomic) SEL completeSelector; +@property(nonatomic, assign) PRTweenTimingFunction timingFunction; + +#if NS_BLOCKS_AVAILABLE +@property(nonatomic, copy) PRTweenUpdateBlock updateBlock; +@property(nonatomic, copy) PRTweenCompleteBlock completeBlock; +#endif + +@property(nonatomic, assign) CGFloat *boundRef; +@property(nonatomic, retain) id boundObject; +@property(nonatomic) SEL boundGetter; +@property(nonatomic) SEL boundSetter; +@property(nonatomic) BOOL override; +@property(nonatomic) BOOL wasPreempted; + +@property(nonatomic) PRTweenHasTweenedObserverOptions observers; + +@end + +@interface PRTweenCGPointLerp : NSObject ++ (PRTweenOperation *)lerp:(id)object + property:(NSString *)property + from:(CGPoint)from + to:(CGPoint)to + duration:(CGFloat)duration + timingFunction:(PRTweenTimingFunction)timingFunction + target:(NSObject *)target + completeSelector:(SEL)selector; + ++ (PRTweenOperation *)lerp:(id)object + property:(NSString *)property + from:(CGPoint)from + to:(CGPoint)to + duration:(CGFloat)duration + delay:(CGFloat)delay + timingFunction:(PRTweenTimingFunction)timingFunction + target:(NSObject *)target + completeSelector:(SEL)selector; + ++ (PRTweenOperation *)lerp:(id)object + property:(NSString *)property + from:(CGPoint)from + to:(CGPoint)to + duration:(CGFloat)duration; + +#if NS_BLOCKS_AVAILABLE + ++ (PRTweenOperation *)lerp:(id)object + property:(NSString *)property + from:(CGPoint)from + to:(CGPoint)to + duration:(CGFloat)duration + timingFunction:(PRTweenTimingFunction)timingFunction + updateBlock:(PRTweenUpdateBlock)updateBlock + completeBlock:(PRTweenCompleteBlock)completeBlock; + ++ (PRTweenOperation *)lerp:(id)object + property:(NSString *)property + from:(CGPoint)from + to:(CGPoint)to + duration:(CGFloat)duration + delay:(CGFloat)delay + timingFunction:(PRTweenTimingFunction)timingFunction + updateBlock:(PRTweenUpdateBlock)updateBlock + completeBlock:(PRTweenCompleteBlock)completeBlock; + +#endif +@end + +@interface PRTweenCGRectLerp : NSObject ++ (PRTweenOperation *)lerp:(id)object + property:(NSString *)property + from:(CGRect)from + to:(CGRect)to + duration:(CGFloat)duration + timingFunction:(PRTweenTimingFunction)timingFunction + target:(NSObject *)target + completeSelector:(SEL)selector; + ++ (PRTweenOperation *)lerp:(id)object + property:(NSString *)property + from:(CGRect)from + to:(CGRect)to + duration:(CGFloat)duration + delay:(CGFloat)delay + timingFunction:(PRTweenTimingFunction)timingFunction + target:(NSObject *)target + completeSelector:(SEL)selector; + ++ (PRTweenOperation *)lerp:(id)object + property:(NSString *)property + from:(CGRect)from + to:(CGRect)to + duration:(CGFloat)duration; + +#if NS_BLOCKS_AVAILABLE + ++ (PRTweenOperation *)lerp:(id)object + property:(NSString *)property + from:(CGRect)from + to:(CGRect)to + duration:(CGFloat)duration + timingFunction:(PRTweenTimingFunction)timingFunction + updateBlock:(PRTweenUpdateBlock)updateBlock + completeBlock:(PRTweenCompleteBlock)completeBlock; + ++ (PRTweenOperation *)lerp:(id)object + property:(NSString *)property + from:(CGRect)from + to:(CGRect)to + duration:(CGFloat)duration + delay:(CGFloat)delay + timingFunction:(PRTweenTimingFunction)timingFunction + updateBlock:(PRTweenUpdateBlock)updateBlock + completeBlock:(PRTweenCompleteBlock)completeBlock; + +#endif +@end + +@interface PRTweenCGSizeLerp : NSObject ++ (PRTweenOperation *)lerp:(id)object + property:(NSString *)property + from:(CGSize)from + to:(CGSize)to + duration:(CGFloat)duration + timingFunction:(PRTweenTimingFunction)timingFunction + target:(NSObject *)target + completeSelector:(SEL)selector; + ++ (PRTweenOperation *)lerp:(id)object + property:(NSString *)property + from:(CGSize)from + to:(CGSize)to + duration:(CGFloat)duration + delay:(CGFloat)delay + timingFunction:(PRTweenTimingFunction)timingFunction + target:(NSObject *)target completeSelector:(SEL)selector; + ++ (PRTweenOperation *)lerp:(id)object + property:(NSString *)property + from:(CGSize)from + to:(CGSize)to + duration:(CGFloat)duration; + +#if NS_BLOCKS_AVAILABLE + ++ (PRTweenOperation *)lerp:(id)object + property:(NSString *)property + from:(CGSize)from + to:(CGSize)to + duration:(CGFloat)duration + timingFunction:(PRTweenTimingFunction)timingFunction + updateBlock:(PRTweenUpdateBlock)updateBlock + completeBlock:(PRTweenCompleteBlock)completeBlock; + +//+ (PRTweenOperation *)lerp:(id)object +// property:(NSString *)property +// from:(CGSize)from +// to:(CGSize)to +// duration:(CGFloat)duration +// delay:(CGFloat)delay +// timingFunction:(PRTweenTimingFunction)timingFunction +// updateBlock:(PRTweenUpdateBlock)updateBlock +// completeBlock:(PRTweenCompleteBlock)completeBlock; + +#endif +@end + +@interface PRTween : NSObject { + NSMutableArray *tweenOperations; + NSMutableArray *expiredTweenOperations; + NSTimer *timer; + CGFloat timeOffset; + + PRTweenTimingFunction defaultTimingFunction; + BOOL useBuiltInAnimationsWhenPossible; +} + +@property(nonatomic, readonly) CGFloat timeOffset; +@property(nonatomic, assign) PRTweenTimingFunction defaultTimingFunction; +@property(nonatomic, assign) BOOL useBuiltInAnimationsWhenPossible; + ++ (PRTween *)sharedInstance; + ++ (PRTweenOperation *)tween:(id)object + property:(NSString *)property + from:(CGFloat)from + to:(CGFloat)to + duration:(CGFloat)duration + timingFunction:(PRTweenTimingFunction)timingFunction + target:(NSObject *)target + completeSelector:(SEL)selector; + ++ (PRTweenOperation *)tween:(CGFloat *)ref + from:(CGFloat)from + to:(CGFloat)to + duration:(CGFloat)duration + timingFunction:(PRTweenTimingFunction)timingFunction + target:(NSObject *)target + completeSelector:(SEL)selector; + ++ (PRTweenOperation *)tween:(CGFloat *)ref + from:(CGFloat)from + to:(CGFloat)to + duration:(CGFloat)duration + delay:(CGFloat)delay + timingFunction:(PRTweenTimingFunction)timingFunction + target:(NSObject *)target + completeSelector:(SEL)selector; + ++ (PRTweenOperation *)tween:(id)object + property:(NSString *)property + from:(CGFloat)from + to:(CGFloat)to + duration:(CGFloat)duration; + ++ (PRTweenOperation *)tween:(CGFloat *)ref + from:(CGFloat)from + to:(CGFloat)to + duration:(CGFloat)duration; + ++ (PRTweenOperation *)lerp:(id)object + property:(NSString *)property + period:(PRTweenLerpPeriod *)period + timingFunction:(PRTweenTimingFunction)timingFunction + target:(NSObject *)target + completeSelector:(SEL)selector; + +- (PRTweenOperation *)addTweenOperation:(PRTweenOperation *)operation; + +- (PRTweenOperation *)addTweenPeriod:(PRTweenPeriod *)period + target:(NSObject *)target + selector:(SEL)selector; + +- (PRTweenOperation *)addTweenPeriod:(PRTweenPeriod *)period + target:(NSObject *)target + selector:(SEL)selector + timingFunction:(PRTweenTimingFunction)timingFunction; + +- (void)removeTweenOperation:(PRTweenOperation *)tweenOperation; + +- (void)removeAllTweenOperations; + +#if NS_BLOCKS_AVAILABLE + ++ (PRTweenOperation *)tween:(id)object + property:(NSString *)property + from:(CGFloat)from + to:(CGFloat)to + duration:(CGFloat)duration + timingFunction:(PRTweenTimingFunction)timingFunction + updateBlock:(PRTweenUpdateBlock)updateBlock + completeBlock:(PRTweenCompleteBlock)completeBlock; + ++ (PRTweenOperation *)tween:(id)object + property:(NSString *)property + from:(CGFloat)from + to:(CGFloat)to + duration:(CGFloat)duration + delay:(CGFloat)delay + timingFunction:(PRTweenTimingFunction)timingFunction + updateBlock:(PRTweenUpdateBlock)updateBlock + completeBlock:(PRTweenCompleteBlock)completeBlock; + ++ (PRTweenOperation *)tween:(CGFloat *)ref + from:(CGFloat)from to:(CGFloat)to + duration:(CGFloat)duration + timingFunction:(PRTweenTimingFunction)timingFunction + updateBlock:(PRTweenUpdateBlock)updateBlock + completeBlock:(PRTweenCompleteBlock)completeBlock; + ++ (PRTweenOperation *)tween:(CGFloat *)ref + from:(CGFloat)from + to:(CGFloat)to + duration:(CGFloat)duration + delay:(CGFloat)delay + timingFunction:(PRTweenTimingFunction)timingFunction + updateBlock:(PRTweenUpdateBlock)updateBlock + completeBlock:(PRTweenCompleteBlock)completeBlock; + ++ (PRTweenOperation *)lerp:(id)object + property:(NSString *)property + period:(PRTweenLerpPeriod *)period + timingFunction:(PRTweenTimingFunction)timingFunction + updateBlock:(PRTweenUpdateBlock)updateBlock + completeBlock:(PRTweenCompleteBlock)completeBlock; + +- (PRTweenOperation *)addTweenPeriod:(PRTweenPeriod *)period + updateBlock:(PRTweenUpdateBlock)updateBlock + completionBlock:(PRTweenCompleteBlock)completeBlock; + +- (PRTweenOperation *)addTweenPeriod:(PRTweenPeriod *)period + updateBlock:(PRTweenUpdateBlock)updateBlock + completionBlock:(PRTweenCompleteBlock)completionBlock + timingFunction:(PRTweenTimingFunction)timingFunction; + +#endif + +@end diff --git a/KACircleProgressView/External/PRTween/lib/PRTween.m b/KACircleProgressView/External/PRTween/lib/PRTween.m new file mode 100755 index 0000000..b654374 --- /dev/null +++ b/KACircleProgressView/External/PRTween/lib/PRTween.m @@ -0,0 +1,1175 @@ + +#import "PRTween.h" + +#define kPRTweenFramerate 1.0/60 + +@implementation PRTweenPeriod +@synthesize startValue; +@synthesize endValue; +@synthesize tweenedValue; +@synthesize duration; +@synthesize delay; +@synthesize startOffset; + ++ (id)periodWithStartValue:(CGFloat)aStartValue + endValue:(CGFloat)anEndValue + duration:(CGFloat)duration { + + PRTweenPeriod *period = [PRTweenPeriod new]; + + period.startValue = period.tweenedValue = aStartValue; + period.endValue = anEndValue; + period.duration = duration; + period.startOffset = [[PRTween sharedInstance] timeOffset]; + + return period; +} + ++ (id)periodWithStartValue:(CGFloat)aStartValue + endValue:(CGFloat)anEndValue + duration:(CGFloat)duration + delay:(CGFloat)delay { + + PRTweenPeriod *period = [PRTweenPeriod new]; + + period.startValue = period.tweenedValue = aStartValue; + period.endValue = anEndValue; + period.duration = duration; + period.delay = delay; + period.startOffset = [[PRTween sharedInstance] timeOffset]; + + return period; +} + +@end + +@implementation PRTweenLerpPeriod +@synthesize startLerp; +@synthesize endLerp; +@synthesize tweenedLerp; + ++ (id)periodWithStartValue:(NSValue *)aStartValue + endValue:(NSValue *)anEndValue + duration:(CGFloat)duration { + + PRTweenLerpPeriod *period = [[self class] new]; + period.startLerp = aStartValue; + period.tweenedLerp = aStartValue; + period.endLerp = anEndValue; + period.duration = duration; + period.startOffset = [[PRTween sharedInstance] timeOffset]; + + return period; +} + ++ (id)periodWithStartValue:(NSValue *)aStartValue + endValue:(NSValue *)anEndValue + duration:(CGFloat)duration + delay:(CGFloat)delay { + + PRTweenLerpPeriod *period = [[self class] new]; + period.startLerp = aStartValue; + period.tweenedLerp = aStartValue; + period.endLerp = anEndValue; + period.duration = duration; + period.delay = delay; + period.startOffset = [[PRTween sharedInstance] timeOffset]; + + return period; +} + +@end + +@implementation PRTweenCGPointLerpPeriod + ++ (id)periodWithStartCGPoint:(CGPoint)aStartPoint + endCGPoint:(CGPoint)anEndPoint + duration:(CGFloat)duration { + + return [PRTweenCGPointLerpPeriod periodWithStartValue:[NSValue valueWithCGPoint:aStartPoint] endValue:[NSValue valueWithCGPoint:anEndPoint] duration:duration]; +} + +- (CGPoint)startCGPoint { + return [self.startLerp CGPointValue]; +} + +- (CGPoint)tweenedCGPoint { + return [self.tweenedLerp CGPointValue]; +} + +- (CGPoint)endCGPoint { + return [self.endLerp CGPointValue]; +} + +- (NSValue *)tweenedValueForProgress:(CGFloat)progress { + + CGPoint startPoint = self.startCGPoint; + CGPoint endPoint = self.endCGPoint; + CGPoint distance = CGPointMake(endPoint.x - startPoint.x, endPoint.y - startPoint.y); + CGPoint tweenedPoint = CGPointMake(startPoint.x + distance.x * progress, startPoint.y + distance.y * progress); + + return [NSValue valueWithCGPoint:tweenedPoint]; + +} + +- (void)setProgress:(CGFloat)progress { + self.tweenedLerp = [self tweenedValueForProgress:progress]; +} + +@end + +@implementation PRTweenCGRectLerpPeriod + ++ (id)periodWithStartCGRect:(CGRect)aStartRect + endCGRect:(CGRect)anEndRect + duration:(CGFloat)duration { + + return [PRTweenCGRectLerpPeriod periodWithStartValue:[NSValue valueWithCGRect:aStartRect] endValue:[NSValue valueWithCGRect:anEndRect] duration:duration]; +} + +- (CGRect)startCGRect { + return [self.startLerp CGRectValue]; +} + +- (CGRect)tweenedCGRect { + return [self.tweenedLerp CGRectValue]; +} + +- (CGRect)endCGRect { + return [self.endLerp CGRectValue]; +} + +- (NSValue *)tweenedValueForProgress:(CGFloat)progress { + + CGRect startRect = self.startCGRect; + CGRect endRect = self.endCGRect; + CGRect distance = CGRectMake(endRect.origin.x - startRect.origin.x, endRect.origin.y - startRect.origin.y, endRect.size.width - startRect.size.width, endRect.size.height - startRect.size.height); + CGRect tweenedRect = CGRectMake(startRect.origin.x + distance.origin.x * progress, startRect.origin.y + distance.origin.y * progress, startRect.size.width + distance.size.width * progress, startRect.size.height + distance.size.height * progress); + + return [NSValue valueWithCGRect:tweenedRect]; + +} + +- (void)setProgress:(CGFloat)progress { + self.tweenedLerp = [self tweenedValueForProgress:progress]; +} + +@end + +@implementation PRTweenCGSizeLerpPeriod + ++ (id)periodWithStartCGSize:(CGSize)aStartSize + endCGSize:(CGSize)anEndSize + duration:(CGFloat)duration { + + return [PRTweenCGRectLerpPeriod periodWithStartValue:[NSValue valueWithCGSize:aStartSize] endValue:[NSValue valueWithCGSize:anEndSize] duration:duration]; +} + ++ (id)periodWithStartCGSize:(CGSize)aStartSize + endCGSize:(CGSize)anEndSize + duration:(CGFloat)duration + delay:(CGFloat)delay { + + return [PRTweenCGRectLerpPeriod periodWithStartValue:[NSValue valueWithCGSize:aStartSize] endValue:[NSValue valueWithCGSize:anEndSize] duration:duration delay:delay]; +} + +- (CGSize)startCGSize { + return [self.startLerp CGSizeValue]; +} + +- (CGSize)tweenedCGSize { + return [self.tweenedLerp CGSizeValue]; +} + +- (CGSize)endCGSize { + return [self.endLerp CGSizeValue]; +} + +- (NSValue *)tweenedValueForProgress:(CGFloat)progress { + + CGSize startSize = self.startCGSize; + CGSize endSize = self.endCGSize; + CGSize distance = CGSizeMake(endSize.width - startSize.width, endSize.height - startSize.height); + CGSize tweenedSize = CGSizeMake(startSize.width + distance.width * progress, startSize.height + distance.height * progress); + return [NSValue valueWithCGSize:tweenedSize]; + +} + +- (void)setProgress:(CGFloat)progress { + self.tweenedLerp = [self tweenedValueForProgress:progress]; +} + +@end + +@interface PRTweenOperation () +@property(nonatomic) BOOL canUseBuiltAnimation; +@end + +@implementation PRTweenOperation +@synthesize period; +@synthesize target; +@synthesize updateSelector; +@synthesize completeSelector; +@synthesize timingFunction; +@synthesize boundRef; +@synthesize boundObject; +@synthesize boundGetter; +@synthesize boundSetter; +@synthesize canUseBuiltAnimation; +@synthesize override; +@synthesize wasPreempted; +@synthesize observers; + +#if NS_BLOCKS_AVAILABLE +@synthesize updateBlock; +@synthesize completeBlock; +#endif + +@end + +@implementation PRTweenCGPointLerp + ++ (PRTweenOperation *)lerp:(id)object + property:(NSString *)property + from:(CGPoint)from + to:(CGPoint)to + duration:(CGFloat)duration + timingFunction:(PRTweenTimingFunction)timingFunction + target:(NSObject *)target + completeSelector:(SEL)selector { + + return [PRTween lerp:object + property:property + period:[PRTweenCGPointLerpPeriod + periodWithStartCGPoint:from + endCGPoint:to + duration:duration] + timingFunction:timingFunction + target:target + completeSelector:selector]; +} + ++ (PRTweenOperation *)lerp:(id)object + property:(NSString *)property + from:(CGPoint)from + to:(CGPoint)to + duration:(CGFloat)duration + delay:(CGFloat)delay + timingFunction:(PRTweenTimingFunction)timingFunction + target:(NSObject *)target + completeSelector:(SEL)selector { + + PRTweenCGPointLerpPeriod *period = [PRTweenCGPointLerpPeriod periodWithStartCGPoint:from endCGPoint:to duration:duration]; + period.delay = delay; + + return [PRTween lerp:object + property:property + period:period + timingFunction:timingFunction + target:target + completeSelector:selector]; +} + ++ (PRTweenOperation *)lerp:(id)object + property:(NSString *)property + from:(CGPoint)from + to:(CGPoint)to + duration:(CGFloat)duration { + + return [PRTweenCGPointLerp + lerp:object + property:property + from:from + to:to + duration:duration + timingFunction:NULL target:nil completeSelector:NULL]; +} + +#if NS_BLOCKS_AVAILABLE + ++ (PRTweenOperation *)lerp:(id)object + property:(NSString *)property + from:(CGPoint)from + to:(CGPoint)to + duration:(CGFloat)duration + timingFunction:(PRTweenTimingFunction)timingFunction + updateBlock:(PRTweenUpdateBlock)updateBlock + completeBlock:(PRTweenCompleteBlock)completeBlock { + + return [PRTween lerp:object + property:property + period:[PRTweenCGPointLerpPeriod + periodWithStartCGPoint:from + endCGPoint:to + duration:duration] + timingFunction:timingFunction + updateBlock:updateBlock + completeBlock:completeBlock]; +} + ++ (PRTweenOperation *)lerp:(id)object + property:(NSString *)property + from:(CGPoint)from + to:(CGPoint)to + duration:(CGFloat)duration + delay:(CGFloat)delay + timingFunction:(PRTweenTimingFunction)timingFunction + updateBlock:(PRTweenUpdateBlock)updateBlock + completeBlock:(PRTweenCompleteBlock)completeBlock { + + PRTweenCGPointLerpPeriod *period = [PRTweenCGPointLerpPeriod periodWithStartCGPoint:from endCGPoint:to duration:duration]; + [period setDelay:delay]; + + return [PRTween lerp:object property:property period:period timingFunction:timingFunction updateBlock:updateBlock completeBlock:completeBlock]; +} + +#endif + +@end + +@implementation PRTweenCGRectLerp + ++ (PRTweenOperation *)lerp:(id)object + property:(NSString *)property + from:(CGRect)from + to:(CGRect)to + duration:(CGFloat)duration + timingFunction:(PRTweenTimingFunction)timingFunction + target:(NSObject *)target + completeSelector:(SEL)selector { + + return [PRTween lerp:object + property:property + period:[PRTweenCGRectLerpPeriod + periodWithStartCGRect:from + endCGRect:to + duration:duration] + timingFunction:timingFunction + target:target + completeSelector:selector]; +} + ++ (PRTweenOperation *)lerp:(id)object + property:(NSString *)property + from:(CGRect)from + to:(CGRect)to + duration:(CGFloat)duration + delay:(CGFloat)delay + timingFunction:(PRTweenTimingFunction)timingFunction + target:(NSObject *)target + completeSelector:(SEL)selector { + + PRTweenCGRectLerpPeriod *period = [PRTweenCGRectLerpPeriod periodWithStartCGRect:from + endCGRect:to + duration:duration]; + period.delay = delay; + return [PRTween lerp:object + property:property + period:period + timingFunction:timingFunction + target:target + completeSelector:selector]; +} + ++ (PRTweenOperation *)lerp:(id)object + property:(NSString *)property + from:(CGRect)from + to:(CGRect)to + duration:(CGFloat)duration { + + return [PRTweenCGRectLerp lerp:object + property:property + from:from + to:to + duration:duration + timingFunction:NULL target:nil completeSelector:NULL]; +} + +#if NS_BLOCKS_AVAILABLE + ++ (PRTweenOperation *)lerp:(id)object + property:(NSString *)property + from:(CGRect)from + to:(CGRect)to + duration:(CGFloat)duration + timingFunction:(PRTweenTimingFunction)timingFunction + updateBlock:(PRTweenUpdateBlock)updateBlock + completeBlock:(PRTweenCompleteBlock)completeBlock { + return [PRTween lerp:object property:property period:[PRTweenCGRectLerpPeriod periodWithStartCGRect:from endCGRect:to duration:duration] timingFunction:timingFunction updateBlock:updateBlock completeBlock:completeBlock]; +} + ++ (PRTweenOperation *)lerp:(id)object + property:(NSString *)property + from:(CGRect)from + to:(CGRect)to + duration:(CGFloat)duration + delay:(CGFloat)delay + timingFunction:(PRTweenTimingFunction)timingFunction + updateBlock:(PRTweenUpdateBlock)updateBlock + completeBlock:(PRTweenCompleteBlock)completeBlock { + + PRTweenCGRectLerpPeriod *period = [PRTweenCGRectLerpPeriod periodWithStartCGRect:from endCGRect:to duration:duration]; + [period setDelay:delay]; + + return [PRTween lerp:object property:property period:period timingFunction:timingFunction updateBlock:updateBlock completeBlock:completeBlock]; +} + +#endif + +@end + +@implementation PRTweenCGSizeLerp + ++ (PRTweenOperation *)lerp:(id)object + property:(NSString *)property + from:(CGSize)from + to:(CGSize)to + duration:(CGFloat)duration + timingFunction:(PRTweenTimingFunction)timingFunction + target:(NSObject *)target + completeSelector:(SEL)selector { + + return [PRTween lerp:object + property:property + period:[PRTweenCGSizeLerpPeriod + periodWithStartCGSize:from + endCGSize:to + duration:duration] + timingFunction:timingFunction + target:target + completeSelector:selector]; +} + ++ (PRTweenOperation *)lerp:(id)object + property:(NSString *)property + from:(CGSize)from + to:(CGSize)to + duration:(CGFloat)duration + delay:(CGFloat)delay + timingFunction:(PRTweenTimingFunction)timingFunction + target:(NSObject *)target + completeSelector:(SEL)selector { + + PRTweenCGPointLerpPeriod *period = [PRTweenCGSizeLerpPeriod periodWithStartCGSize:from + endCGSize:to + duration:duration]; + period.delay = delay; + return [PRTween lerp:object + property:property + period:period + timingFunction:timingFunction + target:target + completeSelector:selector]; +} + ++ (PRTweenOperation *)lerp:(id)object + property:(NSString *)property + from:(CGSize)from + to:(CGSize)to + duration:(CGFloat)duration { + + return [PRTweenCGSizeLerp lerp:object + property:property + from:from + to:to + duration:duration + timingFunction:NULL target:nil completeSelector:NULL]; +} + +#if NS_BLOCKS_AVAILABLE + ++ (PRTweenOperation *)lerp:(id)object + property:(NSString *)property + from:(CGSize)from + to:(CGSize)to + duration:(CGFloat)duration + timingFunction:(PRTweenTimingFunction)timingFunction + updateBlock:(PRTweenUpdateBlock)updateBlock + completeBlock:(PRTweenCompleteBlock)completeBlock { + + return [PRTween lerp:object + property:property + period:[PRTweenCGSizeLerpPeriod + periodWithStartCGSize:from + endCGSize:to + duration:duration] + timingFunction:timingFunction + updateBlock:updateBlock + completeBlock:completeBlock]; +} + +#endif + +@end + +@interface PRTween () ++ (SEL)setterFromProperty:(NSString *)property; + +- (void)update; +@end + +static PRTween *instance = nil; +static NSArray *animationSelectorsForCoreAnimation = nil; +static NSArray *animationSelectorsForUIView = nil; + +@implementation PRTween +@synthesize timeOffset; +@synthesize defaultTimingFunction; +@synthesize useBuiltInAnimationsWhenPossible; + ++ (PRTween *)sharedInstance { + if (instance == nil) { + instance = [[PRTween alloc] init]; + instance.useBuiltInAnimationsWhenPossible = YES; + } + return instance; +} + ++ (PRTweenOperation *)tween:(id)object + property:(NSString *)property + from:(CGFloat)from + to:(CGFloat)to + duration:(CGFloat)duration + timingFunction:(PRTweenTimingFunction)timingFunction + target:(NSObject *)target + completeSelector:(SEL)selector { + + PRTweenPeriod *period = [PRTweenPeriod periodWithStartValue:from + endValue:to + duration:duration]; + PRTweenOperation *operation = [PRTweenOperation new]; + operation.period = period; + operation.timingFunction = timingFunction; + operation.target = target; + operation.completeSelector = selector; + operation.boundObject = object; + operation.boundGetter = NSSelectorFromString([NSString stringWithFormat:@"%@", property]); + operation.boundSetter = [PRTween setterFromProperty:property]; + operation.wasPreempted = NO; + [self addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedValue" observerOptions:PRTweenHasTweenedValueObserver operation:operation]; + + [[PRTween sharedInstance] performSelector:@selector(addTweenOperation:) withObject:operation afterDelay:0]; + return operation; + +} + ++ (PRTweenOperation *)tween:(CGFloat *)ref + from:(CGFloat)from + to:(CGFloat)to + duration:(CGFloat)duration + timingFunction:(PRTweenTimingFunction)timingFunction + target:(NSObject *)target + completeSelector:(SEL)selector { + + PRTweenPeriod *period = [PRTweenPeriod periodWithStartValue:from + endValue:to + duration:duration]; + PRTweenOperation *operation = [PRTweenOperation new]; + operation.period = period; + operation.timingFunction = timingFunction; + operation.target = target; + operation.completeSelector = selector; + operation.boundRef = ref; + operation.wasPreempted = NO; + [self addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedValue" observerOptions:PRTweenHasTweenedValueObserver operation:operation]; + + [[PRTween sharedInstance] performSelector:@selector(addTweenOperation:) withObject:operation afterDelay:0 inModes:[NSArray arrayWithObject:NSRunLoopCommonModes]]; + return operation; + +} + ++ (PRTweenOperation *)tween:(CGFloat *)ref + from:(CGFloat)from + to:(CGFloat)to + duration:(CGFloat)duration + delay:(CGFloat)delay + timingFunction:(PRTweenTimingFunction)timingFunction + target:(NSObject *)target + completeSelector:(SEL)selector { + + PRTweenPeriod *period = [PRTweenPeriod periodWithStartValue:from + endValue:to + duration:duration + delay:delay]; + PRTweenOperation *operation = [PRTweenOperation new]; + operation.period = period; + operation.timingFunction = timingFunction; + operation.target = target; + operation.completeSelector = selector; + operation.boundRef = ref; + operation.wasPreempted = NO; + [self addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedValue" observerOptions:PRTweenHasTweenedValueObserver operation:operation]; + + [[PRTween sharedInstance] performSelector:@selector(addTweenOperation:) withObject:operation afterDelay:0 inModes:[NSArray arrayWithObject:NSRunLoopCommonModes]]; + return operation; + +} + ++ (PRTweenOperation *)tween:(id)object + property:(NSString *)property + from:(CGFloat)from + to:(CGFloat)to + duration:(CGFloat)duration { + + return [PRTween tween:object + property:property + from:from + to:to + duration:duration + timingFunction:NULL target:nil completeSelector:NULL]; +} + ++ (PRTweenOperation *)tween:(CGFloat *)ref + from:(CGFloat)from + to:(CGFloat)to + duration:(CGFloat)duration { + + return [PRTween tween:ref + from:from + to:to + duration:duration + timingFunction:NULL target:nil completeSelector:NULL]; +} + ++ (PRTweenOperation *)lerp:(id)object + property:(NSString *)property + period:(PRTweenLerpPeriod *)period + timingFunction:(PRTweenTimingFunction)timingFunction + target:(NSObject *)target + completeSelector:(SEL)selector { + + //PRTweenPeriod *period = [PRTweenLerpPeriod periodWithStartValue:from endValue:to duration:duration]; + PRTweenOperation *operation = [PRTweenOperation new]; + operation.period = period; + operation.timingFunction = timingFunction; + operation.target = target; + operation.completeSelector = selector; + operation.boundObject = object; + operation.boundGetter = NSSelectorFromString([NSString stringWithFormat:@"%@", property]); + operation.boundSetter = [PRTween setterFromProperty:property]; + operation.wasPreempted = NO; + [self addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedLerp" observerOptions:PRTweenHasTweenedLerpObserver operation:operation]; + + [[PRTween sharedInstance] performSelector:@selector(addTweenOperation:) withObject:operation afterDelay:0 inModes:[NSArray arrayWithObject:NSRunLoopCommonModes]]; + return operation; + +} + +#if NS_BLOCKS_AVAILABLE + ++ (PRTweenOperation *)tween:(id)object + property:(NSString *)property + from:(CGFloat)from + to:(CGFloat)to + duration:(CGFloat)duration + timingFunction:(PRTweenTimingFunction)timingFunction + updateBlock:(PRTweenUpdateBlock)updateBlock + completeBlock:(PRTweenCompleteBlock)completeBlock { + + PRTweenPeriod *period = [PRTweenPeriod periodWithStartValue:from + endValue:to + duration:duration]; + PRTweenOperation *operation = [PRTweenOperation new]; + operation.period = period; + operation.timingFunction = timingFunction; + operation.updateBlock = updateBlock; + operation.completeBlock = completeBlock; + operation.boundObject = object; + operation.boundGetter = NSSelectorFromString([NSString stringWithFormat:@"%@", property]); + operation.boundSetter = [PRTween setterFromProperty:property]; + operation.wasPreempted = NO; + [self addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedValue" observerOptions:PRTweenHasTweenedValueObserver operation:operation]; + + [[PRTween sharedInstance] performSelector:@selector(addTweenOperation:) withObject:operation afterDelay:0]; + return operation; + +} + ++ (PRTweenOperation *)tween:(id)object + property:(NSString *)property + from:(CGFloat)from + to:(CGFloat)to + duration:(CGFloat)duration + delay:(CGFloat)delay + timingFunction:(PRTweenTimingFunction)timingFunction + updateBlock:(PRTweenUpdateBlock)updateBlock + completeBlock:(PRTweenCompleteBlock)completeBlock { + + PRTweenPeriod *period = [PRTweenPeriod periodWithStartValue:from + endValue:to + duration:duration + delay:delay]; + PRTweenOperation *operation = [PRTweenOperation new]; + operation.period = period; + operation.timingFunction = timingFunction; + operation.updateBlock = updateBlock; + operation.completeBlock = completeBlock; + operation.boundObject = object; + operation.boundGetter = NSSelectorFromString([NSString stringWithFormat:@"%@", property]); + operation.boundSetter = [PRTween setterFromProperty:property]; + operation.wasPreempted = NO; + [self addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedValue" observerOptions:PRTweenHasTweenedValueObserver operation:operation]; + + [[PRTween sharedInstance] performSelector:@selector(addTweenOperation:) withObject:operation afterDelay:0]; + return operation; + +} + ++ (PRTweenOperation *)tween:(CGFloat *)ref + from:(CGFloat)from + to:(CGFloat)to + duration:(CGFloat)duration + timingFunction:(PRTweenTimingFunction)timingFunction + updateBlock:(PRTweenUpdateBlock)updateBlock + completeBlock:(PRTweenCompleteBlock)completeBlock { + + PRTweenPeriod *period = [PRTweenPeriod periodWithStartValue:from + endValue:to + duration:duration]; + PRTweenOperation *operation = [PRTweenOperation new]; + operation.period = period; + operation.timingFunction = timingFunction; + operation.updateBlock = updateBlock; + operation.completeBlock = completeBlock; + operation.boundRef = ref; + operation.wasPreempted = NO; + [self addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedValue" observerOptions:PRTweenHasTweenedValueObserver operation:operation]; + + [[PRTween sharedInstance] performSelector:@selector(addTweenOperation:) withObject:operation afterDelay:0 inModes:[NSArray arrayWithObject:NSRunLoopCommonModes]]; + return operation; + +} + ++ (PRTweenOperation *)tween:(CGFloat *)ref + from:(CGFloat)from + to:(CGFloat)to + duration:(CGFloat)duration + delay:(CGFloat)delay + timingFunction:(PRTweenTimingFunction)timingFunction + updateBlock:(PRTweenUpdateBlock)updateBlock + completeBlock:(PRTweenCompleteBlock)completeBlock { + + PRTweenPeriod *period = [PRTweenPeriod periodWithStartValue:from + endValue:to + duration:duration + delay:delay]; + PRTweenOperation *operation = [PRTweenOperation new]; + operation.period = period; + operation.timingFunction = timingFunction; + operation.updateBlock = updateBlock; + operation.completeBlock = completeBlock; + operation.boundRef = ref; + operation.wasPreempted = NO; + [self addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedValue" observerOptions:PRTweenHasTweenedValueObserver operation:operation]; + + [[PRTween sharedInstance] performSelector:@selector(addTweenOperation:) withObject:operation afterDelay:0 inModes:[NSArray arrayWithObject:NSRunLoopCommonModes]]; + return operation; + +} + ++ (PRTweenOperation *)lerp:(id)object + property:(NSString *)property + period:(PRTweenLerpPeriod *)period + timingFunction:(PRTweenTimingFunction)timingFunction + updateBlock:(PRTweenUpdateBlock)updateBlock + completeBlock:(PRTweenCompleteBlock)completeBlock { + + //PRTweenPeriod *period = [PRTweenLerpPeriod periodWithStartValue:from endValue:to duration:duration]; + PRTweenOperation *operation = [PRTweenOperation new]; + operation.period = period; + operation.timingFunction = timingFunction; + operation.updateBlock = updateBlock; + operation.completeBlock = completeBlock; + operation.boundObject = object; + operation.boundGetter = NSSelectorFromString([NSString stringWithFormat:@"%@", property]); + operation.boundSetter = [PRTween setterFromProperty:property]; + operation.wasPreempted = NO; + [self addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedLerp" observerOptions:PRTweenHasTweenedLerpObserver operation:operation]; + + [[PRTween sharedInstance] performSelector:@selector(addTweenOperation:) withObject:operation afterDelay:0 inModes:[NSArray arrayWithObject:NSRunLoopCommonModes]]; + return operation; + +} + +#endif + ++ (void)addObserver:(NSObject *)observer + forKeyPath:(NSString *)keyPath + observerOptions:(PRTweenHasTweenedObserverOptions)observerOptions + operation:(PRTweenOperation *)operation { + + [operation addObserver:observer forKeyPath:keyPath options:NSKeyValueObservingOptionNew context:NULL]; + operation.observers = operation.observers | observerOptions; +} + +- (void)observeValueForKeyPath:(NSString *)keyPath + ofObject:(id)object + change:(NSDictionary *)change + context:(void *)context { + + PRTweenOperation *operation = (PRTweenOperation *) object; + + if ([operation.period isKindOfClass:[PRTweenLerpPeriod class]]) { + PRTweenLerpPeriod *lerpPeriod = (PRTweenLerpPeriod *) operation.period; + + NSUInteger bufferSize = 0; + NSGetSizeAndAlignment([lerpPeriod.tweenedLerp objCType], &bufferSize, NULL); + void *tweenedValue = malloc(bufferSize); + [lerpPeriod.tweenedLerp getValue:tweenedValue]; + + if (operation.boundObject && [operation.boundObject respondsToSelector:operation.boundGetter] && [operation.boundObject respondsToSelector:operation.boundSetter]) { + NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[[operation.boundObject class] + instanceMethodSignatureForSelector:operation.boundSetter]]; + [invocation setTarget:operation.boundObject]; + [invocation setSelector:operation.boundSetter]; + [invocation setArgument:tweenedValue atIndex:2]; + [invocation invoke]; + } + + free(tweenedValue); + + } else { + + CGFloat tweenedValue = operation.period.tweenedValue; + + if (operation.boundObject && [operation.boundObject respondsToSelector:operation.boundGetter] && [operation.boundObject respondsToSelector:operation.boundSetter]) { + NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[[operation.boundObject class] + instanceMethodSignatureForSelector:operation.boundSetter]]; + [invocation setTarget:operation.boundObject]; + [invocation setSelector:operation.boundSetter]; + [invocation setArgument:&tweenedValue atIndex:2]; + [invocation invoke]; + } else if (operation.boundRef) { + *operation.boundRef = tweenedValue; + } + + } + +} + +- (id)init { + self = [super init]; + if (self != nil) { + tweenOperations = [[NSMutableArray alloc] init]; + expiredTweenOperations = [[NSMutableArray alloc] init]; + timeOffset = 0; + if (timer == nil) { + timer = [NSTimer scheduledTimerWithTimeInterval:kPRTweenFramerate target:self selector:@selector(update) userInfo:nil repeats:YES]; + [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes]; + } + self.defaultTimingFunction = &PRTweenTimingFunctionQuadInOut; + } + return self; +} + +- (PRTweenOperation *)addTweenOperation:(PRTweenOperation *)operation { + + if (useBuiltInAnimationsWhenPossible && !operation.override) { + + if (animationSelectorsForCoreAnimation == nil) { + animationSelectorsForCoreAnimation = [[NSArray alloc] initWithObjects: + @"setBounds:", // CGRect + @"setPosition:", // CGPoint + @"setZPosition:", // CGFloat + @"setAnchorPoint:", // CGPoint + @"setAnchorPointZ:", // CGFloat + //@"setTransform:", // CATransform3D + //@"setSublayerTransform:", // CATransform3D + @"setFrame:", // CGRect + @"setContentsRect" // CGRect + @"setContentsScale:", // CGFloat + @"setContentsCenter:", // CGPoint + //@"setBackgroundColor:", // CGColorRef + @"setCornerRadius:", // CGFloat + @"setBorderWidth:", // CGFloat + @"setOpacity:", // CGFloat + //@"setShadowColor:", // CGColorRef + @"setShadowOpacity:", // CGFloat + @"setShadowOffset:", // CGSize + @"setShadowRadius:", // CGFloat + //@"setShadowPath:", + nil]; + } + + if (animationSelectorsForUIView == nil) { + animationSelectorsForUIView = [[NSArray alloc] initWithObjects: + @"setFrame:", // CGRect + @"setBounds:", // CGRect + @"setCenter:", // CGPoint + @"setTransform:", // CGAffineTransform + @"setAlpha:", // CGFloat + //@"setBackgroundColor:", // UIColor + @"setContentStretch:", // CGRect + nil]; + } + + if (operation.boundSetter && operation.boundObject && !(operation.timingFunction == &PRTweenTimingFunctionCADefault || + operation.timingFunction == &PRTweenTimingFunctionCAEaseIn || + operation.timingFunction == &PRTweenTimingFunctionCAEaseOut || + operation.timingFunction == &PRTweenTimingFunctionCAEaseInOut || + operation.timingFunction == &PRTweenTimingFunctionCALinear || + operation.timingFunction == &PRTweenTimingFunctionUIViewEaseIn || + operation.timingFunction == &PRTweenTimingFunctionUIViewEaseOut || + operation.timingFunction == &PRTweenTimingFunctionUIViewEaseInOut || + operation.timingFunction == &PRTweenTimingFunctionUIViewLinear || + operation.timingFunction == NULL)) { + goto complete; + } + + + if (operation.boundSetter && operation.boundObject && [operation.boundObject isKindOfClass:[CALayer class]]) { + for (NSString *selector in animationSelectorsForCoreAnimation) { + NSString *setter = NSStringFromSelector(operation.boundSetter); + if ([selector isEqualToString:setter]) { + NSLog(@"Using Core Animation for %@", NSStringFromSelector(operation.boundSetter)); + operation.canUseBuiltAnimation = YES; + + NSString *propertyUnformatted = [selector stringByReplacingCharactersInRange:NSMakeRange(0, 3) withString:@""]; + NSString *propertyFormatted = [[propertyUnformatted stringByReplacingCharactersInRange:NSMakeRange(0, 1) withString:[[propertyUnformatted substringToIndex:1] + lowercaseString]] substringToIndex:[propertyUnformatted length] - 1]; + //NSLog(@"%@", propertyFormatted); + CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:propertyFormatted]; + animation.duration = operation.period.duration; + + if (![operation.period isKindOfClass:[PRTweenLerpPeriod class]] && ![operation.period conformsToProtocol:@protocol(PRTweenLerpPeriod)]) { + animation.fromValue = [NSNumber numberWithFloat:operation.period.startValue]; + animation.toValue = [NSNumber numberWithFloat:operation.period.endValue]; + } else { + PRTweenLerpPeriod *period = (PRTweenLerpPeriod *) operation.period; + animation.fromValue = period.startLerp; + animation.toValue = period.endLerp; + } + + if (operation.timingFunction == &PRTweenTimingFunctionCAEaseIn) { + animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]; + } else if (operation.timingFunction == &PRTweenTimingFunctionCAEaseOut) { + animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]; + } else if (operation.timingFunction == &PRTweenTimingFunctionCAEaseInOut) { + animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; + } else if (operation.timingFunction == &PRTweenTimingFunctionCALinear) { + animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; + } else { + animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault]; + } + + [operation.boundObject setValue:animation.toValue forKeyPath:propertyFormatted]; + [operation.boundObject addAnimation:animation forKey:@"PRTweenCAAnimation"]; + + goto complete; + } + } + } else if (operation.boundSetter && operation.boundObject && [operation.boundObject isKindOfClass:[UIView class]]) { + for (NSString *selector in animationSelectorsForUIView) { + NSString *setter = NSStringFromSelector(operation.boundSetter); + if ([selector isEqualToString:setter]) { + NSLog(@"Using UIView Animation for %@", NSStringFromSelector(operation.boundSetter)); + operation.canUseBuiltAnimation = YES; + + NSString *propertyUnformatted = [selector stringByReplacingCharactersInRange:NSMakeRange(0, 3) withString:@""]; + NSString *propertyFormatted = [[propertyUnformatted stringByReplacingCharactersInRange:NSMakeRange(0, 1) withString:[[propertyUnformatted substringToIndex:1] + lowercaseString]] substringToIndex:[propertyUnformatted length] - 1]; + + NSValue *fromValue = nil; + NSValue *toValue = nil; + + if (![operation.period isKindOfClass:[PRTweenLerpPeriod class]] && ![operation.period conformsToProtocol:@protocol(PRTweenLerpPeriod)]) { + fromValue = [NSNumber numberWithFloat:operation.period.startValue]; + toValue = [NSNumber numberWithFloat:operation.period.endValue]; + } else { + PRTweenLerpPeriod *period = (PRTweenLerpPeriod *) operation.period; + fromValue = period.startLerp; + toValue = period.endLerp; + } + + [operation.boundObject setValue:fromValue forKeyPath:propertyFormatted]; + [UIView beginAnimations:nil context:NULL]; + [UIView setAnimationDuration:operation.period.duration]; + + if (operation.timingFunction == &PRTweenTimingFunctionUIViewEaseIn) { + [UIView setAnimationCurve:UIViewAnimationCurveEaseIn]; + } else if (operation.timingFunction == &PRTweenTimingFunctionUIViewEaseOut) { + [UIView setAnimationCurve:UIViewAnimationCurveEaseOut]; + } else if (operation.timingFunction == &PRTweenTimingFunctionUIViewEaseInOut) { + [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; + } else if (operation.timingFunction == &PRTweenTimingFunctionUIViewLinear) { + [UIView setAnimationCurve:UIViewAnimationCurveLinear]; + } + + [operation.boundObject setValue:toValue forKeyPath:propertyFormatted]; + [UIView commitAnimations]; + + goto complete; + } + } + } + + } + + complete: + [tweenOperations addObject:operation]; + return operation; +} + +#if NS_BLOCKS_AVAILABLE + +- (PRTweenOperation *)addTweenPeriod:(PRTweenPeriod *)period + updateBlock:(void (^)(PRTweenPeriod *period))updateBlock + completionBlock:(void (^)(BOOL finished))completeBlock { + return [self addTweenPeriod:period updateBlock:updateBlock completionBlock:completeBlock timingFunction:self.defaultTimingFunction]; +} + +- (PRTweenOperation *)addTweenPeriod:(PRTweenPeriod *)period + updateBlock:(void (^)(PRTweenPeriod *period))anUpdateBlock + completionBlock:(void (^)(BOOL finished))completeBlock + timingFunction:(PRTweenTimingFunction)timingFunction { + + PRTweenOperation *tweenOperation = [PRTweenOperation new]; + tweenOperation.period = period; + tweenOperation.timingFunction = timingFunction; + tweenOperation.updateBlock = anUpdateBlock; + tweenOperation.completeBlock = completeBlock; + tweenOperation.wasPreempted = NO; + return [self addTweenOperation:tweenOperation]; + +} + +#endif + +- (PRTweenOperation *)addTweenPeriod:(PRTweenPeriod *)period target:(NSObject *)target selector:(SEL)selector { + return [self addTweenPeriod:period target:target selector:selector timingFunction:self.defaultTimingFunction]; +} + +- (PRTweenOperation *)addTweenPeriod:(PRTweenPeriod *)period + target:(NSObject *)target + selector:(SEL)selector + timingFunction:(PRTweenTimingFunction)timingFunction { + + PRTweenOperation *tweenOperation = [PRTweenOperation new]; + tweenOperation.period = period; + tweenOperation.target = target; + tweenOperation.timingFunction = timingFunction; + tweenOperation.updateSelector = selector; + tweenOperation.wasPreempted = NO; + + return [self addTweenOperation:tweenOperation]; + +} + +- (void)removeTweenOperation:(PRTweenOperation *)tweenOperation { + if (tweenOperation != nil) { + if ([tweenOperations containsObject:tweenOperation]) { + tweenOperation.wasPreempted = YES; + [expiredTweenOperations addObject:tweenOperation]; + } + } +} + +- (void)removeAllTweenOperations { + for (PRTweenOperation *tweenOperation in tweenOperations) { + tweenOperation.wasPreempted = YES; + [expiredTweenOperations addObject:tweenOperation]; + } +} + ++ (SEL)setterFromProperty:(NSString *)property { + return NSSelectorFromString([NSString stringWithFormat:@"set%@:", [property stringByReplacingCharactersInRange:NSMakeRange(0, 1) withString:[[property substringToIndex:1] + capitalizedString]]]); +} + +- (void) update { + timeOffset += kPRTweenFramerate; + + for (PRTweenOperation *tweenOperation in tweenOperations) { + + PRTweenPeriod *period = tweenOperation.period; + + // if operation is delayed, pass over it for now + if (timeOffset <= period.startOffset + period.delay) { + continue; + } + + CGFloat (*timingFunction)(CGFloat, CGFloat, CGFloat, CGFloat) = tweenOperation.timingFunction; + if (timingFunction == NULL) { + timingFunction = self.defaultTimingFunction; + } + + if (timingFunction != NULL && tweenOperation.canUseBuiltAnimation == NO) { + if (timeOffset <= period.startOffset + period.delay + period.duration) { + if ([period isKindOfClass:[PRTweenLerpPeriod class]]) { + if ([period conformsToProtocol:@protocol(PRTweenLerpPeriod)]) { + PRTweenLerpPeriod *lerpPeriod = (PRTweenLerpPeriod *) period; + CGFloat progress = timingFunction(timeOffset - period.startOffset - period.delay, 0.0, 1.0, period.duration); + [lerpPeriod setProgress:progress]; + } else { + // @TODO: Throw exception + NSLog(@"Class doesn't conform to PRTweenLerp"); + } + } else { + // if tween operation is valid, calculate tweened value using timing function + period.tweenedValue = timingFunction(timeOffset - period.startOffset - period.delay, period.startValue, period.endValue - period.startValue, period.duration); + } + } else { + // move expired tween operations to list for cleanup + period.tweenedValue = period.endValue; + [expiredTweenOperations addObject:tweenOperation]; + } + + NSObject *target = tweenOperation.target; + SEL selector = tweenOperation.updateSelector; + + if (period != nil) { + if (target != nil && selector != NULL) { + [target performSelector:selector withObject:period afterDelay:0 inModes:[NSArray arrayWithObject:NSRunLoopCommonModes]]; + } + + // Check to see if blocks/GCD are supported + if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_4_0) { + // fire off update block + if (tweenOperation.updateBlock != NULL) { + tweenOperation.updateBlock(period); + } + } + } + } else if (tweenOperation.canUseBuiltAnimation == YES) { + if (timeOffset > period.startOffset + period.delay + period.duration) { + [expiredTweenOperations addObject:tweenOperation]; + } + } + } + + // clean up expired tween operations + for (__strong PRTweenOperation *tweenOperation in expiredTweenOperations) { + + if (tweenOperation.completeSelector) [tweenOperation.target performSelector:tweenOperation.completeSelector withObject:nil afterDelay:0 inModes:[NSArray arrayWithObject:NSRunLoopCommonModes]]; + + // Check to see if blocks/GCD are supported + if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_4_0) { + if (tweenOperation.completeBlock != NULL) { + tweenOperation.completeBlock(!tweenOperation.wasPreempted); + } + } + + if (tweenOperation.observers == PRTweenHasTweenedValueObserver) { + [tweenOperation removeObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedValue"]; + tweenOperation.observers = tweenOperation.observers & ~PRTweenHasTweenedValueObserver; + } + + if (tweenOperation.observers == PRTweenHasTweenedLerpObserver) { + [tweenOperation removeObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedLerp"]; + tweenOperation.observers = tweenOperation.observers & ~PRTweenHasTweenedLerpObserver; + } + + [tweenOperations removeObject:tweenOperation]; + tweenOperation = nil; + } + [expiredTweenOperations removeAllObjects]; +} + +- (void)dealloc { + tweenOperations = nil; + expiredTweenOperations = nil; + + [timer invalidate]; +} + +@end diff --git a/KACircleProgressView/External/PRTween/lib/PRTweenTimingFunctions.h b/KACircleProgressView/External/PRTween/lib/PRTweenTimingFunctions.h new file mode 100755 index 0000000..9b08b9b --- /dev/null +++ b/KACircleProgressView/External/PRTween/lib/PRTweenTimingFunctions.h @@ -0,0 +1,82 @@ +/* + + These timing functions are adapted from Robert Penner's excellent AS2 easing equations. + For more information, check out http://robertpenner.com/easing/ + + -- + + TERMS OF USE - EASING EQUATIONS + + Open source under the BSD License. + + Copyright © 2001 Robert Penner + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + Neither the name of the author nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission. + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +#import +#import + +CGFloat PRTweenTimingFunctionLinear (CGFloat, CGFloat, CGFloat, CGFloat); + +CGFloat PRTweenTimingFunctionBackOut (CGFloat, CGFloat, CGFloat, CGFloat); +CGFloat PRTweenTimingFunctionBackIn (CGFloat, CGFloat, CGFloat, CGFloat); +CGFloat PRTweenTimingFunctionBackInOut (CGFloat, CGFloat, CGFloat, CGFloat); + +CGFloat PRTweenTimingFunctionBounceOut (CGFloat, CGFloat, CGFloat, CGFloat); +CGFloat PRTweenTimingFunctionBounceIn (CGFloat, CGFloat, CGFloat, CGFloat); +CGFloat PRTweenTimingFunctionBounceInOut (CGFloat, CGFloat, CGFloat, CGFloat); + +CGFloat PRTweenTimingFunctionCircOut (CGFloat, CGFloat, CGFloat, CGFloat); +CGFloat PRTweenTimingFunctionCircIn (CGFloat, CGFloat, CGFloat, CGFloat); +CGFloat PRTweenTimingFunctionCircInOut (CGFloat, CGFloat, CGFloat, CGFloat); + +CGFloat PRTweenTimingFunctionCubicOut (CGFloat, CGFloat, CGFloat, CGFloat); +CGFloat PRTweenTimingFunctionCubicIn (CGFloat, CGFloat, CGFloat, CGFloat); +CGFloat PRTweenTimingFunctionCubicInOut (CGFloat, CGFloat, CGFloat, CGFloat); + +CGFloat PRTweenTimingFunctionElasticOut (CGFloat, CGFloat, CGFloat, CGFloat); +CGFloat PRTweenTimingFunctionElasticIn (CGFloat, CGFloat, CGFloat, CGFloat); +CGFloat PRTweenTimingFunctionElasticInOut (CGFloat, CGFloat, CGFloat, CGFloat); + +CGFloat PRTweenTimingFunctionExpoOut (CGFloat, CGFloat, CGFloat, CGFloat); +CGFloat PRTweenTimingFunctionExpoIn (CGFloat, CGFloat, CGFloat, CGFloat); +CGFloat PRTweenTimingFunctionExpoInOut (CGFloat, CGFloat, CGFloat, CGFloat); + +CGFloat PRTweenTimingFunctionQuadOut (CGFloat, CGFloat, CGFloat, CGFloat); +CGFloat PRTweenTimingFunctionQuadIn (CGFloat, CGFloat, CGFloat, CGFloat); +CGFloat PRTweenTimingFunctionQuadInOut (CGFloat, CGFloat, CGFloat, CGFloat); + +CGFloat PRTweenTimingFunctionQuartOut (CGFloat, CGFloat, CGFloat, CGFloat); +CGFloat PRTweenTimingFunctionQuartIn (CGFloat, CGFloat, CGFloat, CGFloat); +CGFloat PRTweenTimingFunctionQuartInOut (CGFloat, CGFloat, CGFloat, CGFloat); + +CGFloat PRTweenTimingFunctionQuintOut (CGFloat, CGFloat, CGFloat, CGFloat); +CGFloat PRTweenTimingFunctionQuintIn (CGFloat, CGFloat, CGFloat, CGFloat); +CGFloat PRTweenTimingFunctionQuintInOut (CGFloat, CGFloat, CGFloat, CGFloat); + +CGFloat PRTweenTimingFunctionSineOut (CGFloat, CGFloat, CGFloat, CGFloat); +CGFloat PRTweenTimingFunctionSineIn (CGFloat, CGFloat, CGFloat, CGFloat); +CGFloat PRTweenTimingFunctionSineInOut (CGFloat, CGFloat, CGFloat, CGFloat); + +CGFloat PRTweenTimingFunctionCALinear (CGFloat, CGFloat, CGFloat, CGFloat); +CGFloat PRTweenTimingFunctionCAEaseIn (CGFloat, CGFloat, CGFloat, CGFloat); +CGFloat PRTweenTimingFunctionCAEaseOut (CGFloat, CGFloat, CGFloat, CGFloat); +CGFloat PRTweenTimingFunctionCAEaseInOut (CGFloat, CGFloat, CGFloat, CGFloat); +CGFloat PRTweenTimingFunctionCADefault (CGFloat, CGFloat, CGFloat, CGFloat); + +CGFloat PRTweenTimingFunctionUIViewLinear (CGFloat, CGFloat, CGFloat, CGFloat); +CGFloat PRTweenTimingFunctionUIViewEaseIn (CGFloat, CGFloat, CGFloat, CGFloat); +CGFloat PRTweenTimingFunctionUIViewEaseOut (CGFloat, CGFloat, CGFloat, CGFloat); +CGFloat PRTweenTimingFunctionUIViewEaseInOut (CGFloat, CGFloat, CGFloat, CGFloat); + +CGFloat (*PRTweenTimingFunctionCACustom(CAMediaTimingFunction *timingFunction))(CGFloat, CGFloat, CGFloat, CGFloat); + + diff --git a/KACircleProgressView/External/PRTween/lib/PRTweenTimingFunctions.m b/KACircleProgressView/External/PRTween/lib/PRTweenTimingFunctions.m new file mode 100755 index 0000000..5161d8a --- /dev/null +++ b/KACircleProgressView/External/PRTween/lib/PRTweenTimingFunctions.m @@ -0,0 +1,230 @@ +/* + + These timing functions are adapted from Robert Penner's excellent AS2 easing equations. + For more information, check out http://robertpenner.com/easing/ + + -- + + TERMS OF USE - EASING EQUATIONS + + Open source under the BSD License. + + Copyright © 2001 Robert Penner + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + Neither the name of the author nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission. + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +#import "PRTweenTimingFunctions.h" + +CGFloat PRTweenTimingFunctionLinear (CGFloat time, CGFloat begin, CGFloat change, CGFloat duration) { + return change * time / duration + begin; +} + +CGFloat PRTweenTimingFunctionBackOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { + CGFloat s = 1.70158; + t=t/d-1; + return c*(t*t*((s+1)*t + s) + 1) + b; +} + +CGFloat PRTweenTimingFunctionBackIn (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { + CGFloat s = 1.70158; + t/=d; + return c*t*t*((s+1)*t - s) + b; +} + +CGFloat PRTweenTimingFunctionBackInOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { + CGFloat s = 1.70158; + if ((t/=d/2) < 1) { + s*=(1.525); + return c/2*(t*t*((s+1)*t - s)) + b; + } + t-=2; + s*=(1.525); + return c/2*(t*t*((s+1)*t + s) + 2) + b; +} + +CGFloat PRTweenTimingFunctionBounceOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { + if ((t/=d) < (1/2.75)) { + return c*(7.5625*t*t) + b; + } else if (t < (2/2.75)) { + t-=(1.5/2.75); + return c*(7.5625*t*t + .75) + b; + } else if (t < (2.5/2.75)) { + t-=(2.25/2.75); + return c*(7.5625*t*t + .9375) + b; + } else { + t-=(2.625/2.75); + return c*(7.5625*t*t + .984375) + b; + } +} + +CGFloat PRTweenTimingFunctionBounceIn (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { + return c - PRTweenTimingFunctionBounceOut(d-t, 0, c, d) + b; +} + +CGFloat PRTweenTimingFunctionBounceInOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { + if (t < d/2) return PRTweenTimingFunctionBounceIn(t*2, 0, c, d) * .5 + b; + else return PRTweenTimingFunctionBounceOut(t*2-d, 0, c, d) * .5 + c*.5 + b; +} + +CGFloat PRTweenTimingFunctionCircOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { + t=t/d-1; + return c * sqrt(1 - t*t) + b; +} + +CGFloat PRTweenTimingFunctionCircIn (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { + t/=d; + return -c * (sqrt(1 - t*t) - 1) + b; +} + +CGFloat PRTweenTimingFunctionCircInOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { + if ((t/=d/2) < 1) return -c/2 * (sqrt(1 - t*t) - 1) + b; + t-=2; + return c/2 * (sqrt(1 - t*t) + 1) + b; +} + +CGFloat PRTweenTimingFunctionCubicOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { + t=t/d-1; + return c*(t*t*t + 1) + b; +} + +CGFloat PRTweenTimingFunctionCubicIn (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { + t/=d; + return c*t*t*t + b; +} + +CGFloat PRTweenTimingFunctionCubicInOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { + if ((t/=d/2) < 1) return c/2*t*t*t + b; + t-=2; + return c/2*(t*t*t + 2) + b; +} + +CGFloat PRTweenTimingFunctionElasticOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { + CGFloat p = d*.3; + CGFloat s, a = .0; + if (t==0) return b; if ((t/=d)==1) return b+c; + if (!a || a < ABS(c)) { a=c; s=p/4; } + else s = p/(2*M_PI) * asin (c/a); + return (a*pow(2,-10*t) * sin( (t*d-s)*(2*M_PI)/p ) + c + b); +} + +CGFloat PRTweenTimingFunctionElasticIn (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { + CGFloat p = d*.3; + CGFloat s, a = .0; + if (t==0) return b; if ((t/=d)==1) return b+c; + if (!a || a < ABS(c)) { a=c; s=p/4; } + else s = p/(2*M_PI) * asin (c/a); + t-=1; + return -(a*pow(2,10*t) * sin( (t*d-s)*(2*M_PI)/p )) + b; +} + +CGFloat PRTweenTimingFunctionElasticInOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { + CGFloat p = d*(.3*1.5); + CGFloat s, a = .0; + if (t==0) return b; if ((t/=d/2)==2) return b+c; + if (!a || a < ABS(c)) { a=c; s=p/4; } + else s = p/(2*M_PI) * asin (c/a); + if (t < 1) { + t-=1; + return -.5*(a*pow(2,10*t) * sin( (t*d-s)*(2*M_PI)/p )) + b; + } + t-=1; + return a*pow(2,-10*t) * sin( (t*d-s)*(2*M_PI)/p )*.5 + c + b; +} + +CGFloat PRTweenTimingFunctionExpoOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { + return (t==d) ? b+c : c * (-pow(2, -10 * t/d) + 1) + b; +} + +CGFloat PRTweenTimingFunctionExpoIn (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { + return (t==0) ? b : c * pow(2, 10 * (t/d - 1)) + b; +} + +CGFloat PRTweenTimingFunctionExpoInOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { + if (t==0) return b; + if (t==d) return b+c; + if ((t/=d/2) < 1) return c/2 * pow(2, 10 * (t - 1)) + b; + return c/2 * (-pow(2, -10 * --t) + 2) + b; +} + +CGFloat PRTweenTimingFunctionQuadOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { + t/=d; + return -c *t*(t-2) + b; +} + +CGFloat PRTweenTimingFunctionQuadIn (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { + t/=d; + return c*t*t + b; +} + +CGFloat PRTweenTimingFunctionQuadInOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { + if ((t/=d/2) < 1) return c/2*t*t + b; + t--; + return -c/2 * (t*(t-2) - 1) + b; +} + +CGFloat PRTweenTimingFunctionQuartOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { + t=t/d-1; + return -c * (t*t*t*t - 1) + b; +} + +CGFloat PRTweenTimingFunctionQuartIn (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { + t/=d; + return c*t*t*t*t + b; +} + +CGFloat PRTweenTimingFunctionQuartInOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { + if ((t/=d/2) < 1) return c/2*t*t*t*t + b; + t-=2; + return -c/2 * (t*t*t*t - 2) + b; +} + +CGFloat PRTweenTimingFunctionQuintOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { + t=t/d-1; + return c*(t*t*t*t*t + 1) + b; +} + +CGFloat PRTweenTimingFunctionQuintIn (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { + t/=d; + return c*t*t*t*t*t + b; +} + +CGFloat PRTweenTimingFunctionQuintInOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { + if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b; + t-=2; + return c/2*(t*t*t*t*t + 2) + b; +} + +CGFloat PRTweenTimingFunctionSineOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { + return c * sin(t/d * (M_PI/2)) + b; +} + +CGFloat PRTweenTimingFunctionSineIn (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { + return -c * cos(t/d * (M_PI/2)) + c + b; +} + +CGFloat PRTweenTimingFunctionSineInOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { + return -c/2 * (cos(M_PI*t/d) - 1) + b; +} + +CGFloat PRTweenTimingFunctionCALinear (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { return 0; } +CGFloat PRTweenTimingFunctionCAEaseIn (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { return 0; } +CGFloat PRTweenTimingFunctionCAEaseOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { return 0; } +CGFloat PRTweenTimingFunctionCAEaseInOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { return 0; } +CGFloat PRTweenTimingFunctionCADefault (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { return 0; } + +CGFloat PRTweenTimingFunctionUIViewLinear (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { return 0; } +CGFloat PRTweenTimingFunctionUIViewEaseIn (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { return 0; } +CGFloat PRTweenTimingFunctionUIViewEaseOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { return 0; } +CGFloat PRTweenTimingFunctionUIViewEaseInOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { return 0; } + +CGFloat (*PRTweenTimingFunctionCACustom(CAMediaTimingFunction *timingFunction))(CGFloat, CGFloat, CGFloat, CGFloat) { + return &PRTweenTimingFunctionLinear; +} diff --git a/KACircleProgressView/KAAppDelegate.m b/KACircleProgressView/KAAppDelegate.m old mode 100644 new mode 100755 index 6769987..cfb5e06 --- a/KACircleProgressView/KAAppDelegate.m +++ b/KACircleProgressView/KAAppDelegate.m @@ -13,10 +13,14 @@ @implementation KAAppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; - KAViewController * kavc = [[KAViewController alloc] initWithNibName:nil bundle:nil]; - UINavigationController * n = [[UINavigationController alloc] initWithRootViewController:kavc]; - [kavc setTitle:@"KACircleProgressView"]; - [self.window setRootViewController:n]; + + KAViewController * kaVC = [[KAViewController alloc] initWithNibName:nil bundle:nil]; + [kaVC setTitle:@"KACircleProgressView"]; + UINavigationController *kaNC = [[UINavigationController alloc]initWithRootViewController:kaVC]; + kaNC.navigationBar.translucent = NO; + + + [self.window setRootViewController:kaNC]; [self.window makeKeyAndVisible]; // Override point for customization after application launch. return YES; diff --git a/KACircleProgressView/KAViewController.h b/KACircleProgressView/KAViewController.h old mode 100644 new mode 100755 index e424507..55240c6 --- a/KACircleProgressView/KAViewController.h +++ b/KACircleProgressView/KAViewController.h @@ -8,6 +8,14 @@ #import #import "KACircleProgressView.h" -@interface KAViewController : UIViewController +@interface KAViewController : UIViewController{ + UISlider *slider0; + UISlider *slider1; + UILabel *lblProgress;; + UILabel *lblDuration;; + double duration; + KACircleProgressView * circlePV; + +} @end diff --git a/KACircleProgressView/KAViewController.m b/KACircleProgressView/KAViewController.m old mode 100644 new mode 100755 index 5def469..3a92f6e --- a/KACircleProgressView/KAViewController.m +++ b/KACircleProgressView/KAViewController.m @@ -7,6 +7,7 @@ // #import "KAViewController.h" +#import "PRTween.h" @interface KAViewController () @@ -16,20 +17,98 @@ @implementation KAViewController - (void)viewDidLoad { + [super viewDidLoad]; + // KACircleProgressView * c = [[KACircleProgressView alloc] initWithSize:20 withType:KACircleProgressViewTypeCircleBacked andProgressBarLineWidth:1 andCircleBackLineWidth:1]; - KACircleProgressView * c = [[KACircleProgressView alloc] initWithSize:100 withType:KACircleProgressViewTypeCircleBacked andProgressBarLineWidth:7 andCircleBackLineWidth:7]; - [c setProgress:0.3]; // set progress to 0.1 out of 1.0 - [self.view addSubview:c]; - [c setCenter:CGPointMake([[UIScreen mainScreen] bounds].size.width/2, [[UIScreen mainScreen] bounds].size.height/2)]; + circlePV = [[KACircleProgressView alloc] initWithSize:100 withType:KACircleProgressViewTypeCircleBacked andProgressBarLineWidth:7 andCircleBackLineWidth:7]; + [circlePV setProgress:0.3]; // set progress to 0.1 out of 1.0 + [self.view addSubview:circlePV]; + [circlePV setCenter:CGPointMake([[UIScreen mainScreen] bounds].size.width/2, [[UIScreen mainScreen] bounds].size.height/2)]; //[self performSelector:@selector(upDate:) withObject:c afterDelay:0.05]; - [super viewDidLoad]; + + + slider0 = [[UISlider alloc]initWithFrame:CGRectMake(10, 20, 200, 30)]; + [slider0 setMinimumValue:0]; + [slider0 setMaximumValue:.99999]; + [slider0 setContinuous:YES]; + [slider0 setValue:0.3]; + [self.view addSubview:slider0]; + [slider0 addTarget:self action:@selector(handleValueChanged:event:) forControlEvents:UIControlEventValueChanged]; + + slider1 = [[UISlider alloc]initWithFrame:CGRectMake(10, 140, 300, 30)]; + [slider1 setMinimumValue:0]; + [slider1 setMaximumValue:5]; + [slider1 setContinuous:YES]; + [slider1 setValue:.50]; + [self.view addSubview:slider1]; + [slider1 addTarget:self action:@selector(slider1ValueChanged) forControlEvents:UIControlEventValueChanged]; + + + duration = 2.00; + lblProgress = [[UILabel alloc] initWithFrame:CGRectMake(0, 50, 300, 30)]; + lblProgress.textAlignment = NSTextAlignmentCenter; + lblProgress.lineBreakMode = NSLineBreakByClipping; + lblProgress.backgroundColor = [UIColor clearColor]; + lblProgress.text = @"Progress"; + lblProgress.textColor = [UIColor whiteColor]; + [self.view addSubview:lblProgress]; + + lblDuration = [[UILabel alloc] initWithFrame:CGRectMake(0, 200, 300, 30)]; + lblDuration.textAlignment = NSTextAlignmentCenter; + lblDuration.lineBreakMode = NSLineBreakByClipping; + lblDuration.backgroundColor = [UIColor clearColor]; + + lblDuration.text = [NSString stringWithFormat:@"Animation Duration (%.2f) seconds",duration]; + lblDuration.textColor = [UIColor whiteColor]; + [self.view addSubview:lblDuration]; + + +} + +-(void)slider1ValueChanged{ + + lblDuration.text = [NSString stringWithFormat:@"Animation Duration (%.2f) seconds",slider1.value ]; + duration = slider1.value; + +} + + + +- (void)handleValueChanged:(id)sender event:(id)event { + + int percent = slider0.value *100; + lblProgress.text = [NSString stringWithFormat:@"Progress value (%d %@)",percent,@"%"]; + + UITouch *touchEvent = [[event allTouches] anyObject]; // there's only one touch + if (touchEvent.phase == UITouchPhaseEnded) { + + /* place your code here */ + [self animate]; + } +} +-(void)animate{ + + PRTweenPeriod *period = [PRTweenPeriod periodWithStartValue:0 endValue:slider0.value duration:duration]; + + PRTweenOperation *operation = [PRTweenOperation new]; + operation.period = period; + operation.target = self; + operation.timingFunction = &PRTweenTimingFunctionLinear; + operation.updateSelector = @selector(update:); + + [[PRTween sharedInstance] addTweenOperation:operation]; } -// testing setting progress by adding 0.01 ever 0.05 seconds -//- (void)upDate:(KACircleProgressView *)c{ -// [c setProgress:c.progress+0.01]; -// [self performSelector:@selector(upDate:) withObject:c afterDelay:0.05]; -//} +- (void)update:(PRTweenPeriod*)period { + // NSLog(@"update %.2f",period.tweenedValue); + CGFloat f =period.tweenedValue; + + [circlePV setProgress:f]; + [circlePV setNeedsDisplay]; + +} + + @end From 85de513a59dd2b50d519716e83775b04b57ab9bb Mon Sep 17 00:00:00 2001 From: John Pope Date: Wed, 4 Dec 2013 10:57:31 +1100 Subject: [PATCH 2/6] use button to refresh add cocoa pod PRTween --- .gitignore | 1 + .../project.pbxproj | 1137 ++++++++++++----- .../contents.xcworkspacedata | 1 + KACircleProgressView/KACircleProgressView.h | 5 +- KACircleProgressView/KACircleProgressView.m | 33 +- KACircleProgressView/KAViewController.h | 2 + KACircleProgressView/KAViewController.m | 39 +- Podfile | 1 + Podfile.lock | 10 + README.md | 5 + 10 files changed, 878 insertions(+), 356 deletions(-) create mode 100644 KACircleProgressView.xcworkspace/contents.xcworkspacedata mode change 100644 => 100755 KACircleProgressView/KACircleProgressView.h mode change 100644 => 100755 KACircleProgressView/KACircleProgressView.m create mode 100644 Podfile create mode 100644 Podfile.lock diff --git a/.gitignore b/.gitignore index 6e13704..3938113 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,4 @@ DerivedData #CocoaPods Pods +Build \ No newline at end of file diff --git a/KACircleProgressView.xcodeproj/project.pbxproj b/KACircleProgressView.xcodeproj/project.pbxproj index 8b84faa..feec4df 100644 --- a/KACircleProgressView.xcodeproj/project.pbxproj +++ b/KACircleProgressView.xcodeproj/project.pbxproj @@ -1,329 +1,808 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - B9758A78183D9374007ED897 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B9758A77183D9374007ED897 /* Foundation.framework */; }; - B9758A7A183D9374007ED897 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B9758A79183D9374007ED897 /* CoreGraphics.framework */; }; - B9758A7C183D9374007ED897 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B9758A7B183D9374007ED897 /* UIKit.framework */; }; - B9758A82183D9374007ED897 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = B9758A80183D9374007ED897 /* InfoPlist.strings */; }; - B9758A84183D9374007ED897 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = B9758A83183D9374007ED897 /* main.m */; }; - B9758A88183D9374007ED897 /* KAAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = B9758A87183D9374007ED897 /* KAAppDelegate.m */; }; - B9758A91183D9374007ED897 /* KAViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B9758A90183D9374007ED897 /* KAViewController.m */; }; - B9758AB1183D9390007ED897 /* KACircleProgressView.m in Sources */ = {isa = PBXBuildFile; fileRef = B9758AB0183D9390007ED897 /* KACircleProgressView.m */; }; - B9758AB3183DC79A007ED897 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B9758AB2183DC79A007ED897 /* Default-568h@2x.png */; }; -/* End PBXBuildFile section */ - -/* Begin PBXFileReference section */ - B9758A74183D9374007ED897 /* KACircleProgressView.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = KACircleProgressView.app; sourceTree = BUILT_PRODUCTS_DIR; }; - B9758A77183D9374007ED897 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; - B9758A79183D9374007ED897 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; - B9758A7B183D9374007ED897 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; - B9758A7F183D9374007ED897 /* KACircleProgressView-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "KACircleProgressView-Info.plist"; sourceTree = ""; }; - B9758A81183D9374007ED897 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; - B9758A83183D9374007ED897 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - B9758A85183D9374007ED897 /* KACircleProgressView-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "KACircleProgressView-Prefix.pch"; sourceTree = ""; }; - B9758A86183D9374007ED897 /* KAAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KAAppDelegate.h; sourceTree = ""; }; - B9758A87183D9374007ED897 /* KAAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KAAppDelegate.m; sourceTree = ""; }; - B9758A8F183D9374007ED897 /* KAViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KAViewController.h; sourceTree = ""; }; - B9758A90183D9374007ED897 /* KAViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KAViewController.m; sourceTree = ""; }; - B9758A99183D9374007ED897 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; - B9758AAF183D9390007ED897 /* KACircleProgressView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KACircleProgressView.h; sourceTree = ""; }; - B9758AB0183D9390007ED897 /* KACircleProgressView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KACircleProgressView.m; sourceTree = ""; }; - B9758AB2183DC79A007ED897 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - B9758A71183D9374007ED897 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - B9758A7A183D9374007ED897 /* CoreGraphics.framework in Frameworks */, - B9758A7C183D9374007ED897 /* UIKit.framework in Frameworks */, - B9758A78183D9374007ED897 /* Foundation.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - B9758A6B183D9374007ED897 = { - isa = PBXGroup; - children = ( - B9758A7D183D9374007ED897 /* KACircleProgressViewProject */, - B9758A76183D9374007ED897 /* Frameworks */, - B9758A75183D9374007ED897 /* Products */, - ); - sourceTree = ""; - }; - B9758A75183D9374007ED897 /* Products */ = { - isa = PBXGroup; - children = ( - B9758A74183D9374007ED897 /* KACircleProgressView.app */, - ); - name = Products; - sourceTree = ""; - }; - B9758A76183D9374007ED897 /* Frameworks */ = { - isa = PBXGroup; - children = ( - B9758A77183D9374007ED897 /* Foundation.framework */, - B9758A79183D9374007ED897 /* CoreGraphics.framework */, - B9758A7B183D9374007ED897 /* UIKit.framework */, - B9758A99183D9374007ED897 /* XCTest.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; - B9758A7D183D9374007ED897 /* KACircleProgressViewProject */ = { - isa = PBXGroup; - children = ( - B9758A86183D9374007ED897 /* KAAppDelegate.h */, - B9758A87183D9374007ED897 /* KAAppDelegate.m */, - B9758A8F183D9374007ED897 /* KAViewController.h */, - B9758A90183D9374007ED897 /* KAViewController.m */, - B9758AB4183DCC37007ED897 /* KACircleProgressView */, - B9758A7E183D9374007ED897 /* Supporting Files */, - ); - name = KACircleProgressViewProject; - path = KACircleProgressView; - sourceTree = ""; - }; - B9758A7E183D9374007ED897 /* Supporting Files */ = { - isa = PBXGroup; - children = ( - B9758AB2183DC79A007ED897 /* Default-568h@2x.png */, - B9758A7F183D9374007ED897 /* KACircleProgressView-Info.plist */, - B9758A80183D9374007ED897 /* InfoPlist.strings */, - B9758A83183D9374007ED897 /* main.m */, - B9758A85183D9374007ED897 /* KACircleProgressView-Prefix.pch */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - B9758AB4183DCC37007ED897 /* KACircleProgressView */ = { - isa = PBXGroup; - children = ( - B9758AAF183D9390007ED897 /* KACircleProgressView.h */, - B9758AB0183D9390007ED897 /* KACircleProgressView.m */, - ); - name = KACircleProgressView; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - B9758A73183D9374007ED897 /* KACircleProgressView */ = { - isa = PBXNativeTarget; - buildConfigurationList = B9758AA9183D9374007ED897 /* Build configuration list for PBXNativeTarget "KACircleProgressView" */; - buildPhases = ( - B9758A70183D9374007ED897 /* Sources */, - B9758A71183D9374007ED897 /* Frameworks */, - B9758A72183D9374007ED897 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = KACircleProgressView; - productName = KACircleProgressView; - productReference = B9758A74183D9374007ED897 /* KACircleProgressView.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - B9758A6C183D9374007ED897 /* Project object */ = { - isa = PBXProject; - attributes = { - CLASSPREFIX = KA; - LastUpgradeCheck = 0500; - ORGANIZATIONNAME = "Kenneth Parker Ackerson"; - }; - buildConfigurationList = B9758A6F183D9374007ED897 /* Build configuration list for PBXProject "KACircleProgressView" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = B9758A6B183D9374007ED897; - productRefGroup = B9758A75183D9374007ED897 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - B9758A73183D9374007ED897 /* KACircleProgressView */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - B9758A72183D9374007ED897 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - B9758A82183D9374007ED897 /* InfoPlist.strings in Resources */, - B9758AB3183DC79A007ED897 /* Default-568h@2x.png in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - B9758A70183D9374007ED897 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - B9758A91183D9374007ED897 /* KAViewController.m in Sources */, - B9758A88183D9374007ED897 /* KAAppDelegate.m in Sources */, - B9758A84183D9374007ED897 /* main.m in Sources */, - B9758AB1183D9390007ED897 /* KACircleProgressView.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - B9758A80183D9374007ED897 /* InfoPlist.strings */ = { - isa = PBXVariantGroup; - children = ( - B9758A81183D9374007ED897 /* en */, - ); - name = InfoPlist.strings; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - B9758AA7183D9374007ED897 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 7.0; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - B9758AA8183D9374007ED897 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = YES; - ENABLE_NS_ASSERTIONS = NO; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 7.0; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - B9758AAA183D9374007ED897 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "KACircleProgressView/KACircleProgressView-Prefix.pch"; - INFOPLIST_FILE = "KACircleProgressView/KACircleProgressView-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 6.0; - PRODUCT_NAME = "$(TARGET_NAME)"; - WRAPPER_EXTENSION = app; - }; - name = Debug; - }; - B9758AAB183D9374007ED897 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "KACircleProgressView/KACircleProgressView-Prefix.pch"; - INFOPLIST_FILE = "KACircleProgressView/KACircleProgressView-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 6.0; - PRODUCT_NAME = "$(TARGET_NAME)"; - WRAPPER_EXTENSION = app; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - B9758A6F183D9374007ED897 /* Build configuration list for PBXProject "KACircleProgressView" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - B9758AA7183D9374007ED897 /* Debug */, - B9758AA8183D9374007ED897 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - B9758AA9183D9374007ED897 /* Build configuration list for PBXNativeTarget "KACircleProgressView" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - B9758AAA183D9374007ED897 /* Debug */, - B9758AAB183D9374007ED897 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = B9758A6C183D9374007ED897 /* Project object */; -} + + + + + archiveVersion + 1 + classes + + objectVersion + 46 + objects + + 18758E0CB0264AC6AC21FA24 + + fileRef + A9A0D81AC1164BA6A1F9EF0A + isa + PBXBuildFile + + 6F0D76BEDB97458E8DF6C4E5 + + buildActionMask + 2147483647 + files + + inputPaths + + isa + PBXShellScriptBuildPhase + name + Check Pods Manifest.lock + outputPaths + + runOnlyForDeploymentPostprocessing + 0 + shellPath + /bin/sh + shellScript + diff "${PODS_ROOT}/../Podfile.lock" "${PODS_ROOT}/Manifest.lock" > /dev/null +if [[ $? != 0 ]] ; then + cat << EOM +error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation. +EOM + exit 1 +fi + + showEnvVarsInLog + 0 + + A9A0D81AC1164BA6A1F9EF0A + + explicitFileType + archive.ar + includeInIndex + 0 + isa + PBXFileReference + path + libPods.a + sourceTree + BUILT_PRODUCTS_DIR + + B2D5FE4E82A2472DA5289523 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + text.xcconfig + name + Pods.xcconfig + path + Pods/Pods.xcconfig + sourceTree + <group> + + B9758A6B183D9374007ED897 + + children + + B9758A7D183D9374007ED897 + B9758A76183D9374007ED897 + B9758A75183D9374007ED897 + B2D5FE4E82A2472DA5289523 + + isa + PBXGroup + sourceTree + <group> + + B9758A6C183D9374007ED897 + + attributes + + CLASSPREFIX + KA + LastUpgradeCheck + 0500 + ORGANIZATIONNAME + Kenneth Parker Ackerson + + buildConfigurationList + B9758A6F183D9374007ED897 + compatibilityVersion + Xcode 3.2 + developmentRegion + English + hasScannedForEncodings + 0 + isa + PBXProject + knownRegions + + en + Base + + mainGroup + B9758A6B183D9374007ED897 + productRefGroup + B9758A75183D9374007ED897 + projectDirPath + + projectReferences + + projectRoot + + targets + + B9758A73183D9374007ED897 + + + B9758A6F183D9374007ED897 + + buildConfigurations + + B9758AA7183D9374007ED897 + B9758AA8183D9374007ED897 + + defaultConfigurationIsVisible + 0 + defaultConfigurationName + Release + isa + XCConfigurationList + + B9758A70183D9374007ED897 + + buildActionMask + 2147483647 + files + + B9758A91183D9374007ED897 + B9758A88183D9374007ED897 + B9758A84183D9374007ED897 + B9758AB1183D9390007ED897 + + isa + PBXSourcesBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + B9758A71183D9374007ED897 + + buildActionMask + 2147483647 + files + + B9758A7A183D9374007ED897 + B9758A7C183D9374007ED897 + B9758A78183D9374007ED897 + 18758E0CB0264AC6AC21FA24 + + isa + PBXFrameworksBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + B9758A72183D9374007ED897 + + buildActionMask + 2147483647 + files + + B9758A82183D9374007ED897 + B9758AB3183DC79A007ED897 + + isa + PBXResourcesBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + B9758A73183D9374007ED897 + + buildConfigurationList + B9758AA9183D9374007ED897 + buildPhases + + 6F0D76BEDB97458E8DF6C4E5 + B9758A70183D9374007ED897 + B9758A71183D9374007ED897 + B9758A72183D9374007ED897 + F5A2DB8D088441119DF57725 + + buildRules + + dependencies + + isa + PBXNativeTarget + name + KACircleProgressView + productName + KACircleProgressView + productReference + B9758A74183D9374007ED897 + productType + com.apple.product-type.application + + B9758A74183D9374007ED897 + + explicitFileType + wrapper.application + includeInIndex + 0 + isa + PBXFileReference + path + KACircleProgressView.app + sourceTree + BUILT_PRODUCTS_DIR + + B9758A75183D9374007ED897 + + children + + B9758A74183D9374007ED897 + + isa + PBXGroup + name + Products + sourceTree + <group> + + B9758A76183D9374007ED897 + + children + + B9758A77183D9374007ED897 + B9758A79183D9374007ED897 + B9758A7B183D9374007ED897 + B9758A99183D9374007ED897 + A9A0D81AC1164BA6A1F9EF0A + + isa + PBXGroup + name + Frameworks + sourceTree + <group> + + B9758A77183D9374007ED897 + + isa + PBXFileReference + lastKnownFileType + wrapper.framework + name + Foundation.framework + path + System/Library/Frameworks/Foundation.framework + sourceTree + SDKROOT + + B9758A78183D9374007ED897 + + fileRef + B9758A77183D9374007ED897 + isa + PBXBuildFile + + B9758A79183D9374007ED897 + + isa + PBXFileReference + lastKnownFileType + wrapper.framework + name + CoreGraphics.framework + path + System/Library/Frameworks/CoreGraphics.framework + sourceTree + SDKROOT + + B9758A7A183D9374007ED897 + + fileRef + B9758A79183D9374007ED897 + isa + PBXBuildFile + + B9758A7B183D9374007ED897 + + isa + PBXFileReference + lastKnownFileType + wrapper.framework + name + UIKit.framework + path + System/Library/Frameworks/UIKit.framework + sourceTree + SDKROOT + + B9758A7C183D9374007ED897 + + fileRef + B9758A7B183D9374007ED897 + isa + PBXBuildFile + + B9758A7D183D9374007ED897 + + children + + B9758A86183D9374007ED897 + B9758A87183D9374007ED897 + B9758A8F183D9374007ED897 + B9758A90183D9374007ED897 + B9758AB4183DCC37007ED897 + B9758A7E183D9374007ED897 + + isa + PBXGroup + name + KACircleProgressViewProject + path + KACircleProgressView + sourceTree + <group> + + B9758A7E183D9374007ED897 + + children + + B9758AB2183DC79A007ED897 + B9758A7F183D9374007ED897 + B9758A80183D9374007ED897 + B9758A83183D9374007ED897 + B9758A85183D9374007ED897 + + isa + PBXGroup + name + Supporting Files + sourceTree + <group> + + B9758A7F183D9374007ED897 + + isa + PBXFileReference + lastKnownFileType + text.plist.xml + path + KACircleProgressView-Info.plist + sourceTree + <group> + + B9758A80183D9374007ED897 + + children + + B9758A81183D9374007ED897 + + isa + PBXVariantGroup + name + InfoPlist.strings + sourceTree + <group> + + B9758A81183D9374007ED897 + + isa + PBXFileReference + lastKnownFileType + text.plist.strings + name + en + path + en.lproj/InfoPlist.strings + sourceTree + <group> + + B9758A82183D9374007ED897 + + fileRef + B9758A80183D9374007ED897 + isa + PBXBuildFile + + B9758A83183D9374007ED897 + + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + path + main.m + sourceTree + <group> + + B9758A84183D9374007ED897 + + fileRef + B9758A83183D9374007ED897 + isa + PBXBuildFile + + B9758A85183D9374007ED897 + + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + path + KACircleProgressView-Prefix.pch + sourceTree + <group> + + B9758A86183D9374007ED897 + + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + path + KAAppDelegate.h + sourceTree + <group> + + B9758A87183D9374007ED897 + + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + path + KAAppDelegate.m + sourceTree + <group> + + B9758A88183D9374007ED897 + + fileRef + B9758A87183D9374007ED897 + isa + PBXBuildFile + + B9758A8F183D9374007ED897 + + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + path + KAViewController.h + sourceTree + <group> + + B9758A90183D9374007ED897 + + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + path + KAViewController.m + sourceTree + <group> + + B9758A91183D9374007ED897 + + fileRef + B9758A90183D9374007ED897 + isa + PBXBuildFile + + B9758A99183D9374007ED897 + + isa + PBXFileReference + lastKnownFileType + wrapper.framework + name + XCTest.framework + path + Library/Frameworks/XCTest.framework + sourceTree + DEVELOPER_DIR + + B9758AA7183D9374007ED897 + + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + ARCHS + $(ARCHS_STANDARD_INCLUDING_64_BIT) + CLANG_CXX_LANGUAGE_STANDARD + gnu++0x + CLANG_CXX_LIBRARY + libc++ + CLANG_ENABLE_MODULES + YES + CLANG_ENABLE_OBJC_ARC + YES + CLANG_WARN_BOOL_CONVERSION + YES + CLANG_WARN_CONSTANT_CONVERSION + YES + CLANG_WARN_DIRECT_OBJC_ISA_USAGE + YES_ERROR + CLANG_WARN_EMPTY_BODY + YES + CLANG_WARN_ENUM_CONVERSION + YES + CLANG_WARN_INT_CONVERSION + YES + CLANG_WARN_OBJC_ROOT_CLASS + YES_ERROR + CLANG_WARN__DUPLICATE_METHOD_MATCH + YES + CODE_SIGN_IDENTITY[sdk=iphoneos*] + iPhone Developer + COPY_PHASE_STRIP + NO + GCC_C_LANGUAGE_STANDARD + gnu99 + GCC_DYNAMIC_NO_PIC + NO + GCC_OPTIMIZATION_LEVEL + 0 + GCC_PREPROCESSOR_DEFINITIONS + + DEBUG=1 + $(inherited) + + GCC_SYMBOLS_PRIVATE_EXTERN + NO + GCC_WARN_64_TO_32_BIT_CONVERSION + YES + GCC_WARN_ABOUT_RETURN_TYPE + YES_ERROR + GCC_WARN_UNDECLARED_SELECTOR + YES + GCC_WARN_UNINITIALIZED_AUTOS + YES + GCC_WARN_UNUSED_FUNCTION + YES + GCC_WARN_UNUSED_VARIABLE + YES + IPHONEOS_DEPLOYMENT_TARGET + 7.0 + ONLY_ACTIVE_ARCH + YES + SDKROOT + iphoneos + TARGETED_DEVICE_FAMILY + 1,2 + + isa + XCBuildConfiguration + name + Debug + + B9758AA8183D9374007ED897 + + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + ARCHS + $(ARCHS_STANDARD_INCLUDING_64_BIT) + CLANG_CXX_LANGUAGE_STANDARD + gnu++0x + CLANG_CXX_LIBRARY + libc++ + CLANG_ENABLE_MODULES + YES + CLANG_ENABLE_OBJC_ARC + YES + CLANG_WARN_BOOL_CONVERSION + YES + CLANG_WARN_CONSTANT_CONVERSION + YES + CLANG_WARN_DIRECT_OBJC_ISA_USAGE + YES_ERROR + CLANG_WARN_EMPTY_BODY + YES + CLANG_WARN_ENUM_CONVERSION + YES + CLANG_WARN_INT_CONVERSION + YES + CLANG_WARN_OBJC_ROOT_CLASS + YES_ERROR + CLANG_WARN__DUPLICATE_METHOD_MATCH + YES + CODE_SIGN_IDENTITY[sdk=iphoneos*] + iPhone Developer + COPY_PHASE_STRIP + YES + ENABLE_NS_ASSERTIONS + NO + GCC_C_LANGUAGE_STANDARD + gnu99 + GCC_WARN_64_TO_32_BIT_CONVERSION + YES + GCC_WARN_ABOUT_RETURN_TYPE + YES_ERROR + GCC_WARN_UNDECLARED_SELECTOR + YES + GCC_WARN_UNINITIALIZED_AUTOS + YES + GCC_WARN_UNUSED_FUNCTION + YES + GCC_WARN_UNUSED_VARIABLE + YES + IPHONEOS_DEPLOYMENT_TARGET + 7.0 + SDKROOT + iphoneos + TARGETED_DEVICE_FAMILY + 1,2 + VALIDATE_PRODUCT + YES + + isa + XCBuildConfiguration + name + Release + + B9758AA9183D9374007ED897 + + buildConfigurations + + B9758AAA183D9374007ED897 + B9758AAB183D9374007ED897 + + defaultConfigurationIsVisible + 0 + defaultConfigurationName + Release + isa + XCConfigurationList + + B9758AAA183D9374007ED897 + + baseConfigurationReference + B2D5FE4E82A2472DA5289523 + buildSettings + + ASSETCATALOG_COMPILER_APPICON_NAME + AppIcon + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME + LaunchImage + GCC_PRECOMPILE_PREFIX_HEADER + YES + GCC_PREFIX_HEADER + KACircleProgressView/KACircleProgressView-Prefix.pch + INFOPLIST_FILE + KACircleProgressView/KACircleProgressView-Info.plist + IPHONEOS_DEPLOYMENT_TARGET + 6.0 + PRODUCT_NAME + $(TARGET_NAME) + WRAPPER_EXTENSION + app + + isa + XCBuildConfiguration + name + Debug + + B9758AAB183D9374007ED897 + + baseConfigurationReference + B2D5FE4E82A2472DA5289523 + buildSettings + + ASSETCATALOG_COMPILER_APPICON_NAME + AppIcon + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME + LaunchImage + GCC_PRECOMPILE_PREFIX_HEADER + YES + GCC_PREFIX_HEADER + KACircleProgressView/KACircleProgressView-Prefix.pch + INFOPLIST_FILE + KACircleProgressView/KACircleProgressView-Info.plist + IPHONEOS_DEPLOYMENT_TARGET + 6.0 + PRODUCT_NAME + $(TARGET_NAME) + WRAPPER_EXTENSION + app + + isa + XCBuildConfiguration + name + Release + + B9758AAF183D9390007ED897 + + fileEncoding + 4 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + path + KACircleProgressView.h + sourceTree + <group> + + B9758AB0183D9390007ED897 + + fileEncoding + 4 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + path + KACircleProgressView.m + sourceTree + <group> + + B9758AB1183D9390007ED897 + + fileRef + B9758AB0183D9390007ED897 + isa + PBXBuildFile + + B9758AB2183DC79A007ED897 + + isa + PBXFileReference + lastKnownFileType + image.png + path + Default-568h@2x.png + sourceTree + <group> + + B9758AB3183DC79A007ED897 + + fileRef + B9758AB2183DC79A007ED897 + isa + PBXBuildFile + + B9758AB4183DCC37007ED897 + + children + + B9758AAF183D9390007ED897 + B9758AB0183D9390007ED897 + + isa + PBXGroup + name + KACircleProgressView + sourceTree + <group> + + F5A2DB8D088441119DF57725 + + buildActionMask + 2147483647 + files + + inputPaths + + isa + PBXShellScriptBuildPhase + name + Copy Pods Resources + outputPaths + + runOnlyForDeploymentPostprocessing + 0 + shellPath + /bin/sh + shellScript + "${SRCROOT}/Pods/Pods-resources.sh" + + showEnvVarsInLog + 0 + + + rootObject + B9758A6C183D9374007ED897 + + diff --git a/KACircleProgressView.xcworkspace/contents.xcworkspacedata b/KACircleProgressView.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..ce502e4 --- /dev/null +++ b/KACircleProgressView.xcworkspace/contents.xcworkspacedata @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/KACircleProgressView/KACircleProgressView.h b/KACircleProgressView/KACircleProgressView.h old mode 100644 new mode 100755 index 555ae01..2ee799b --- a/KACircleProgressView/KACircleProgressView.h +++ b/KACircleProgressView/KACircleProgressView.h @@ -11,12 +11,15 @@ typedef enum{ } KACircleProgressViewType; // type #import -@interface KACircleProgressView : UIView +@interface KACircleProgressView : UIView{ + +} @property (nonatomic, assign) float progress; // progress of the progress view @property (nonatomic, assign) KACircleProgressViewType type; // type of progress view +@property (nonatomic, strong) UIButton * button; // initializer that takes a size (width AND height of view) and a type of progress view diff --git a/KACircleProgressView/KACircleProgressView.m b/KACircleProgressView/KACircleProgressView.m old mode 100644 new mode 100755 index 36e7604..53f63b2 --- a/KACircleProgressView/KACircleProgressView.m +++ b/KACircleProgressView/KACircleProgressView.m @@ -14,6 +14,7 @@ @interface KACircleProgressView (){ @property (nonatomic, strong) CAShapeLayer * progressBar; // progressbar shape @property (nonatomic, strong) CAShapeLayer * backgroundCircle; // background circle shape + @end @implementation KACircleProgressView #pragma mark - Init Methods - @@ -35,6 +36,7 @@ - (id)initWithSize:(float)size withType:(KACircleProgressViewType)type andProgre NSAssert(type == KACircleProgressViewTypeCirclePlain, @"Should not use this initializer with KACircleProgressViewTypeCirclePlain, please use - (id)initWithSize:(float)size withType:(KACircleProgressViewType)type andProgressBarLineWidth:(int)progressBarLineWidth andCircleBackLineWidth:(int)circlebackLW "); lineWidthOfProgressBar = progressBarLineWidth; lineWidthOfCircleBacking = 0; // default value, if you want to set this use "- (id)initWithSize:(float)size withType:(KACircleProgressViewType)type andProgressBarLineWidth:(int)progressBarLineWidth andCircleBackLineWidth:(int)circlebackLW" + [self createLayersWithType:type]; } return self; @@ -56,16 +58,21 @@ - (id)initWithSize:(float)size withType:(KACircleProgressViewType)type andProgre - (void)createLayersWithType:(KACircleProgressViewType)type{ self.type = type; if (self.type == KACircleProgressViewTypeCircleBacked){ - self.backgroundCircle = [CAShapeLayer layer]; - self.backgroundCircle .strokeColor = [UIColor darkGrayColor].CGColor; - self.backgroundCircle .fillColor = [UIColor clearColor].CGColor; - self.backgroundCircle .lineWidth = lineWidthOfCircleBacking; - [self.layer addSublayer:self.backgroundCircle ]; - UIBezierPath *pathForBackground = [UIBezierPath bezierPath]; - pathForBackground.lineWidth = lineWidthOfCircleBacking; - CGFloat radius = (self.bounds.size.width - (lineWidthOfCircleBacking+lineWidthOfProgressBar)/2.f)/2; - [pathForBackground addArcWithCenter:CGPointMake(self.bounds.size.width/2, self.bounds.size.height/2) radius:radius startAngle:M_PI/2.f endAngle:2.0*M_PI + M_PI/2.f clockwise:YES]; - self.backgroundCircle .path = pathForBackground.CGPath; + + self.button = [UIButton buttonWithType:UIButtonTypeCustom]; + [self.button addTarget:self action:nil forControlEvents:UIControlEventTouchUpInside]; + [self.button setTitle:@"Tap to refresh" forState:UIControlStateNormal]; + self.button.titleLabel.font = [UIFont systemFontOfSize:12]; + + self.button.frame = CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.width); + self.button.clipsToBounds = YES; + self.button.layer.backgroundColor = [UIColor darkGrayColor].CGColor; + self.button.layer.cornerRadius = self.bounds.size.width/2;//half of the width + self.button.layer.borderColor=[UIColor redColor].CGColor; + self.button.layer.borderWidth=lineWidthOfCircleBacking; + + [self addSubview:self.button]; + } self.progressBar = [CAShapeLayer layer]; self.progressBar.lineWidth = lineWidthOfProgressBar; @@ -77,12 +84,6 @@ - (void)createLayersWithType:(KACircleProgressViewType)type{ [self setBackgroundColor:[UIColor clearColor]]; } -// setting color of circled back circle -- (void)setColorOfBackCircle:(UIColor *)color{ - NSAssert(self.type == KACircleProgressViewTypeCircleBacked, @"Should not use this method; there is no such thing as back circle because of type you initiated this view with"); - [self.backgroundCircle setStrokeColor:color.CGColor]; - [self setNeedsDisplay]; -} // setting color of progress bar - (void)setColorOfProgressBar:(UIColor *)color{ diff --git a/KACircleProgressView/KAViewController.h b/KACircleProgressView/KAViewController.h index 55240c6..af39ed1 100755 --- a/KACircleProgressView/KAViewController.h +++ b/KACircleProgressView/KAViewController.h @@ -14,8 +14,10 @@ UILabel *lblProgress;; UILabel *lblDuration;; double duration; + double currentValue; KACircleProgressView * circlePV; + } @end diff --git a/KACircleProgressView/KAViewController.m b/KACircleProgressView/KAViewController.m index 3a92f6e..84d5785 100755 --- a/KACircleProgressView/KAViewController.m +++ b/KACircleProgressView/KAViewController.m @@ -19,15 +19,15 @@ - (void)viewDidLoad { [super viewDidLoad]; - // KACircleProgressView * c = [[KACircleProgressView alloc] initWithSize:20 withType:KACircleProgressViewTypeCircleBacked andProgressBarLineWidth:1 andCircleBackLineWidth:1]; circlePV = [[KACircleProgressView alloc] initWithSize:100 withType:KACircleProgressViewTypeCircleBacked andProgressBarLineWidth:7 andCircleBackLineWidth:7]; [circlePV setProgress:0.3]; // set progress to 0.1 out of 1.0 [self.view addSubview:circlePV]; [circlePV setCenter:CGPointMake([[UIScreen mainScreen] bounds].size.width/2, [[UIScreen mainScreen] bounds].size.height/2)]; - //[self performSelector:@selector(upDate:) withObject:c afterDelay:0.05]; + [circlePV.button addTarget:self action:@selector(refresh) forControlEvents:UIControlEventTouchUpInside]; + [circlePV.button setTitle:@"Tap to refresh" forState:UIControlStateNormal]; - slider0 = [[UISlider alloc]initWithFrame:CGRectMake(10, 20, 200, 30)]; + slider0 = [[UISlider alloc]initWithFrame:CGRectMake(10, 20, 200, 30)]; [slider0 setMinimumValue:0]; [slider0 setMaximumValue:.99999]; [slider0 setContinuous:YES]; @@ -41,11 +41,11 @@ - (void)viewDidLoad [slider1 setContinuous:YES]; [slider1 setValue:.50]; [self.view addSubview:slider1]; - [slider1 addTarget:self action:@selector(slider1ValueChanged) forControlEvents:UIControlEventValueChanged]; + [slider1 addTarget:self action:@selector(slider1ValueChanged) forControlEvents:UIControlEventValueChanged]; duration = 2.00; - lblProgress = [[UILabel alloc] initWithFrame:CGRectMake(0, 50, 300, 30)]; + lblProgress = [[UILabel alloc] initWithFrame:CGRectMake(0, 50, 200, 30)]; lblProgress.textAlignment = NSTextAlignmentCenter; lblProgress.lineBreakMode = NSLineBreakByClipping; lblProgress.backgroundColor = [UIColor clearColor]; @@ -53,7 +53,7 @@ - (void)viewDidLoad lblProgress.textColor = [UIColor whiteColor]; [self.view addSubview:lblProgress]; - lblDuration = [[UILabel alloc] initWithFrame:CGRectMake(0, 200, 300, 30)]; + lblDuration = [[UILabel alloc] initWithFrame:CGRectMake(0, 170, 300, 30)]; lblDuration.textAlignment = NSTextAlignmentCenter; lblDuration.lineBreakMode = NSLineBreakByClipping; lblDuration.backgroundColor = [UIColor clearColor]; @@ -80,15 +80,33 @@ - (void)handleValueChanged:(id)sender event:(id)event { lblProgress.text = [NSString stringWithFormat:@"Progress value (%d %@)",percent,@"%"]; UITouch *touchEvent = [[event allTouches] anyObject]; // there's only one touch - if (touchEvent.phase == UITouchPhaseEnded) { + if (touchEvent.phase == UITouchPhaseBegan) { - /* place your code here */ + currentValue = slider0.value; + } + + if (touchEvent.phase == UITouchPhaseEnded) { [self animate]; } + + +} + +-(void)refresh{ + PRTweenPeriod *period = [PRTweenPeriod periodWithStartValue:slider0.value endValue:0 duration:duration]; + + PRTweenOperation *operation = [PRTweenOperation new]; + operation.period = period; + operation.target = self; + operation.timingFunction = &PRTweenTimingFunctionLinear; + operation.updateSelector = @selector(update:); + + [[PRTween sharedInstance] addTweenOperation:operation]; + } -(void)animate{ - PRTweenPeriod *period = [PRTweenPeriod periodWithStartValue:0 endValue:slider0.value duration:duration]; + PRTweenPeriod *period = [PRTweenPeriod periodWithStartValue:currentValue endValue:slider0.value duration:duration]; PRTweenOperation *operation = [PRTweenOperation new]; operation.period = period; @@ -105,7 +123,8 @@ - (void)update:(PRTweenPeriod*)period { [circlePV setProgress:f]; [circlePV setNeedsDisplay]; - + //[circlePV setColorOfProgressBar:[UIColor colorWithRed:1 green:1-f blue:1-f alpha:1]]; + } diff --git a/Podfile b/Podfile new file mode 100644 index 0000000..f9eafc6 --- /dev/null +++ b/Podfile @@ -0,0 +1 @@ +pod 'PRTween', '~> 0.0.1' \ No newline at end of file diff --git a/Podfile.lock b/Podfile.lock new file mode 100644 index 0000000..f5b1350 --- /dev/null +++ b/Podfile.lock @@ -0,0 +1,10 @@ +PODS: + - PRTween (0.0.1) + +DEPENDENCIES: + - PRTween (~> 0.0.1) + +SPEC CHECKSUMS: + PRTween: d0439e7917031328f81de4910c5b02e202389939 + +COCOAPODS: 0.27.1 diff --git a/README.md b/README.md index 8fd8062..e70074c 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,11 @@ Feature(s): - Dynamic in size, color, line widths (of both progress line AND background circle line) and type. - Easy to implement. - Fully vectorized (no bitmap images). +- animation tweening +- button to refresh + + +run > Pod install to download PRTween dependency ![alt tag](http://thepearapps.com/progressView@2x.png) From 49bbc27113c3142597705538884fb31ef8585940 Mon Sep 17 00:00:00 2001 From: John Pope Date: Wed, 4 Dec 2013 10:59:48 +1100 Subject: [PATCH 3/6] update sample button code. --- KACircleProgressView/KACircleProgressView.m | 4 ++-- KACircleProgressView/KAViewController.m | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/KACircleProgressView/KACircleProgressView.m b/KACircleProgressView/KACircleProgressView.m index 53f63b2..0d3c20e 100755 --- a/KACircleProgressView/KACircleProgressView.m +++ b/KACircleProgressView/KACircleProgressView.m @@ -60,8 +60,8 @@ - (void)createLayersWithType:(KACircleProgressViewType)type{ if (self.type == KACircleProgressViewTypeCircleBacked){ self.button = [UIButton buttonWithType:UIButtonTypeCustom]; - [self.button addTarget:self action:nil forControlEvents:UIControlEventTouchUpInside]; - [self.button setTitle:@"Tap to refresh" forState:UIControlStateNormal]; + //[self.button addTarget:self action:nil forControlEvents:UIControlEventTouchUpInside]; + // [self.button setTitle:@"Tap to refresh" forState:UIControlStateNormal]; self.button.titleLabel.font = [UIFont systemFontOfSize:12]; self.button.frame = CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.width); diff --git a/KACircleProgressView/KAViewController.m b/KACircleProgressView/KAViewController.m index 84d5785..9732c4d 100755 --- a/KACircleProgressView/KAViewController.m +++ b/KACircleProgressView/KAViewController.m @@ -23,6 +23,7 @@ - (void)viewDidLoad [circlePV setProgress:0.3]; // set progress to 0.1 out of 1.0 [self.view addSubview:circlePV]; [circlePV setCenter:CGPointMake([[UIScreen mainScreen] bounds].size.width/2, [[UIScreen mainScreen] bounds].size.height/2)]; + [circlePV.button setBackgroundColor:[UIColor darkGrayColor]]; [circlePV.button addTarget:self action:@selector(refresh) forControlEvents:UIControlEventTouchUpInside]; [circlePV.button setTitle:@"Tap to refresh" forState:UIControlStateNormal]; From 7c41e6c247f0715cf9f6228d8f2ec394c22ca820 Mon Sep 17 00:00:00 2001 From: John Pope Date: Wed, 4 Dec 2013 11:11:25 +1100 Subject: [PATCH 4/6] updated example --- KACircleProgressView/KACircleProgressView.m | 2 ++ KACircleProgressView/KAViewController.m | 10 ++++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/KACircleProgressView/KACircleProgressView.m b/KACircleProgressView/KACircleProgressView.m index 0d3c20e..07c578c 100755 --- a/KACircleProgressView/KACircleProgressView.m +++ b/KACircleProgressView/KACircleProgressView.m @@ -94,6 +94,8 @@ - (void)setColorOfProgressBar:(UIColor *)color{ // This method maintains square frame (width x width) - (void)setFrame:(CGRect)frame{ frame = CGRectMake(frame.origin.x, frame.origin.y, frame.size.width, frame.size.width); + self.button.frame = CGRectMake(0, 0, frame.size.width, frame.size.width); + self.button.layer.cornerRadius = frame.size.width/2; [super setFrame:frame]; } - (void)setProgress:(float)progress{ diff --git a/KACircleProgressView/KAViewController.m b/KACircleProgressView/KAViewController.m index 9732c4d..246214b 100755 --- a/KACircleProgressView/KAViewController.m +++ b/KACircleProgressView/KAViewController.m @@ -18,15 +18,17 @@ @implementation KAViewController - (void)viewDidLoad { [super viewDidLoad]; + self.view.backgroundColor = [UIColor whiteColor]; circlePV = [[KACircleProgressView alloc] initWithSize:100 withType:KACircleProgressViewTypeCircleBacked andProgressBarLineWidth:7 andCircleBackLineWidth:7]; [circlePV setProgress:0.3]; // set progress to 0.1 out of 1.0 [self.view addSubview:circlePV]; [circlePV setCenter:CGPointMake([[UIScreen mainScreen] bounds].size.width/2, [[UIScreen mainScreen] bounds].size.height/2)]; - [circlePV.button setBackgroundColor:[UIColor darkGrayColor]]; + [circlePV.button setBackgroundColor:[UIColor lightGrayColor]]; [circlePV.button addTarget:self action:@selector(refresh) forControlEvents:UIControlEventTouchUpInside]; [circlePV.button setTitle:@"Tap to refresh" forState:UIControlStateNormal]; - + circlePV.button.layer.borderColor=[UIColor darkGrayColor].CGColor; + circlePV.frame = CGRectMake(100, 200, 200, 200); slider0 = [[UISlider alloc]initWithFrame:CGRectMake(10, 20, 200, 30)]; [slider0 setMinimumValue:0]; @@ -51,7 +53,7 @@ - (void)viewDidLoad lblProgress.lineBreakMode = NSLineBreakByClipping; lblProgress.backgroundColor = [UIColor clearColor]; lblProgress.text = @"Progress"; - lblProgress.textColor = [UIColor whiteColor]; + lblProgress.textColor = [UIColor blackColor]; [self.view addSubview:lblProgress]; lblDuration = [[UILabel alloc] initWithFrame:CGRectMake(0, 170, 300, 30)]; @@ -60,7 +62,7 @@ - (void)viewDidLoad lblDuration.backgroundColor = [UIColor clearColor]; lblDuration.text = [NSString stringWithFormat:@"Animation Duration (%.2f) seconds",duration]; - lblDuration.textColor = [UIColor whiteColor]; + lblDuration.textColor = [UIColor blackColor]; [self.view addSubview:lblDuration]; From 4a90aac63bafe46798bbc2e4d15ec50314ade800 Mon Sep 17 00:00:00 2001 From: John Pope Date: Wed, 4 Dec 2013 11:13:49 +1100 Subject: [PATCH 5/6] remove PRTween classes. --- .../External/PRTween/lib/PRTween.h | 443 ------- .../External/PRTween/lib/PRTween.m | 1175 ----------------- .../PRTween/lib/PRTweenTimingFunctions.h | 82 -- .../PRTween/lib/PRTweenTimingFunctions.m | 230 ---- 4 files changed, 1930 deletions(-) delete mode 100755 KACircleProgressView/External/PRTween/lib/PRTween.h delete mode 100755 KACircleProgressView/External/PRTween/lib/PRTween.m delete mode 100755 KACircleProgressView/External/PRTween/lib/PRTweenTimingFunctions.h delete mode 100755 KACircleProgressView/External/PRTween/lib/PRTweenTimingFunctions.m diff --git a/KACircleProgressView/External/PRTween/lib/PRTween.h b/KACircleProgressView/External/PRTween/lib/PRTween.h deleted file mode 100755 index 2f367ef..0000000 --- a/KACircleProgressView/External/PRTween/lib/PRTween.h +++ /dev/null @@ -1,443 +0,0 @@ -#import -#import "PRTweenTimingFunctions.h" - -typedef CGFloat(*PRTweenTimingFunction)(CGFloat, CGFloat, CGFloat, CGFloat); - -#if NS_BLOCKS_AVAILABLE -@class PRTweenPeriod; - -typedef void (^PRTweenUpdateBlock)(PRTweenPeriod *period); - -typedef void (^PRTweenCompleteBlock)(BOOL finished); - -#endif - -enum { - PRTweenHasTweenedValueObserver = 1 << 0, - PRTweenHasTweenedLerpObserver = 1 << 1, -}; -typedef NSUInteger PRTweenHasTweenedObserverOptions; - -@interface PRTweenPeriod : NSObject { - CGFloat duration; - CGFloat delay; - CGFloat startOffset; - CGFloat startValue; - CGFloat endValue; - CGFloat tweenedValue; -} - -@property(nonatomic) CGFloat startValue; -@property(nonatomic) CGFloat endValue; -@property(nonatomic) CGFloat tweenedValue; -@property(nonatomic) CGFloat duration; -@property(nonatomic) CGFloat delay; -@property(nonatomic) CGFloat startOffset; - -+ (id)periodWithStartValue:(CGFloat)aStartValue - endValue:(CGFloat)anEndValue - duration:(CGFloat)duration; - -+ (id)periodWithStartValue:(CGFloat)aStartValue - endValue:(CGFloat)anEndValue - duration:(CGFloat)duration - delay:(CGFloat)delay; - -@end - -@protocol PRTweenLerpPeriod - -- (NSValue *)tweenedValueForProgress:(CGFloat)progress; - -- (void)setProgress:(CGFloat)progress; - -@end - -@interface PRTweenLerpPeriod : PRTweenPeriod { - NSValue *startLerp; - NSValue *endLerp; - NSValue *tweenedLerp; -} - -@property(nonatomic, copy) NSValue *startLerp; -@property(nonatomic, copy) NSValue *endLerp; -@property(nonatomic, copy) NSValue *tweenedLerp; - -+ (id)periodWithStartValue:(NSValue *)aStartValue - endValue:(NSValue *)anEndValue - duration:(CGFloat)duration; - -+ (id)periodWithStartValue:(NSValue *)aStartValue - endValue:(NSValue *)anEndValue - duration:(CGFloat)duration - delay:(CGFloat)delay; -@end - -@interface PRTweenCGPointLerpPeriod : PRTweenLerpPeriod -+ (id)periodWithStartCGPoint:(CGPoint)aStartPoint - endCGPoint:(CGPoint)anEndPoint - duration:(CGFloat)duration; - -- (CGPoint)startCGPoint; - -- (CGPoint)tweenedCGPoint; - -- (CGPoint)endCGPoint; -@end - -@interface PRTweenCGRectLerpPeriod : PRTweenLerpPeriod -+ (id)periodWithStartCGRect:(CGRect)aStartRect - endCGRect:(CGRect)anEndRect - duration:(CGFloat)duration; - -- (CGRect)startCGRect; - -- (CGRect)tweenedCGRect; - -- (CGRect)endCGRect; -@end - -@interface PRTweenCGSizeLerpPeriod : PRTweenLerpPeriod -+ (id)periodWithStartCGSize:(CGSize)aStartSize - endCGSize:(CGSize)anEndSize - duration:(CGFloat)duration; - -+ (id)periodWithStartCGSize:(CGSize)aStartSize - endCGSize:(CGSize)anEndSize - duration:(CGFloat)duration - delay:(CGFloat)delay; - -- (CGSize)startCGSize; - -- (CGSize)tweenedCGSize; - -- (CGSize)endCGSize; -@end - -@interface PRTweenOperation : NSObject { - PRTweenPeriod *period; - NSObject *target; - SEL updateSelector; - SEL completeSelector; - PRTweenTimingFunction timingFunction; - - CGFloat *boundRef; - SEL boundGetter; - SEL boundSetter; - - BOOL override; - BOOL wasPreempted; - - PRTweenHasTweenedObserverOptions observers; - -#if NS_BLOCKS_AVAILABLE - PRTweenUpdateBlock updateBlock; - PRTweenCompleteBlock completeBlock; -#endif - -@private - BOOL canUseBuiltAnimation; -} - -@property(nonatomic, retain) PRTweenPeriod *period; -@property(nonatomic, retain) NSObject *target; -@property(nonatomic) SEL updateSelector; -@property(nonatomic) SEL completeSelector; -@property(nonatomic, assign) PRTweenTimingFunction timingFunction; - -#if NS_BLOCKS_AVAILABLE -@property(nonatomic, copy) PRTweenUpdateBlock updateBlock; -@property(nonatomic, copy) PRTweenCompleteBlock completeBlock; -#endif - -@property(nonatomic, assign) CGFloat *boundRef; -@property(nonatomic, retain) id boundObject; -@property(nonatomic) SEL boundGetter; -@property(nonatomic) SEL boundSetter; -@property(nonatomic) BOOL override; -@property(nonatomic) BOOL wasPreempted; - -@property(nonatomic) PRTweenHasTweenedObserverOptions observers; - -@end - -@interface PRTweenCGPointLerp : NSObject -+ (PRTweenOperation *)lerp:(id)object - property:(NSString *)property - from:(CGPoint)from - to:(CGPoint)to - duration:(CGFloat)duration - timingFunction:(PRTweenTimingFunction)timingFunction - target:(NSObject *)target - completeSelector:(SEL)selector; - -+ (PRTweenOperation *)lerp:(id)object - property:(NSString *)property - from:(CGPoint)from - to:(CGPoint)to - duration:(CGFloat)duration - delay:(CGFloat)delay - timingFunction:(PRTweenTimingFunction)timingFunction - target:(NSObject *)target - completeSelector:(SEL)selector; - -+ (PRTweenOperation *)lerp:(id)object - property:(NSString *)property - from:(CGPoint)from - to:(CGPoint)to - duration:(CGFloat)duration; - -#if NS_BLOCKS_AVAILABLE - -+ (PRTweenOperation *)lerp:(id)object - property:(NSString *)property - from:(CGPoint)from - to:(CGPoint)to - duration:(CGFloat)duration - timingFunction:(PRTweenTimingFunction)timingFunction - updateBlock:(PRTweenUpdateBlock)updateBlock - completeBlock:(PRTweenCompleteBlock)completeBlock; - -+ (PRTweenOperation *)lerp:(id)object - property:(NSString *)property - from:(CGPoint)from - to:(CGPoint)to - duration:(CGFloat)duration - delay:(CGFloat)delay - timingFunction:(PRTweenTimingFunction)timingFunction - updateBlock:(PRTweenUpdateBlock)updateBlock - completeBlock:(PRTweenCompleteBlock)completeBlock; - -#endif -@end - -@interface PRTweenCGRectLerp : NSObject -+ (PRTweenOperation *)lerp:(id)object - property:(NSString *)property - from:(CGRect)from - to:(CGRect)to - duration:(CGFloat)duration - timingFunction:(PRTweenTimingFunction)timingFunction - target:(NSObject *)target - completeSelector:(SEL)selector; - -+ (PRTweenOperation *)lerp:(id)object - property:(NSString *)property - from:(CGRect)from - to:(CGRect)to - duration:(CGFloat)duration - delay:(CGFloat)delay - timingFunction:(PRTweenTimingFunction)timingFunction - target:(NSObject *)target - completeSelector:(SEL)selector; - -+ (PRTweenOperation *)lerp:(id)object - property:(NSString *)property - from:(CGRect)from - to:(CGRect)to - duration:(CGFloat)duration; - -#if NS_BLOCKS_AVAILABLE - -+ (PRTweenOperation *)lerp:(id)object - property:(NSString *)property - from:(CGRect)from - to:(CGRect)to - duration:(CGFloat)duration - timingFunction:(PRTweenTimingFunction)timingFunction - updateBlock:(PRTweenUpdateBlock)updateBlock - completeBlock:(PRTweenCompleteBlock)completeBlock; - -+ (PRTweenOperation *)lerp:(id)object - property:(NSString *)property - from:(CGRect)from - to:(CGRect)to - duration:(CGFloat)duration - delay:(CGFloat)delay - timingFunction:(PRTweenTimingFunction)timingFunction - updateBlock:(PRTweenUpdateBlock)updateBlock - completeBlock:(PRTweenCompleteBlock)completeBlock; - -#endif -@end - -@interface PRTweenCGSizeLerp : NSObject -+ (PRTweenOperation *)lerp:(id)object - property:(NSString *)property - from:(CGSize)from - to:(CGSize)to - duration:(CGFloat)duration - timingFunction:(PRTweenTimingFunction)timingFunction - target:(NSObject *)target - completeSelector:(SEL)selector; - -+ (PRTweenOperation *)lerp:(id)object - property:(NSString *)property - from:(CGSize)from - to:(CGSize)to - duration:(CGFloat)duration - delay:(CGFloat)delay - timingFunction:(PRTweenTimingFunction)timingFunction - target:(NSObject *)target completeSelector:(SEL)selector; - -+ (PRTweenOperation *)lerp:(id)object - property:(NSString *)property - from:(CGSize)from - to:(CGSize)to - duration:(CGFloat)duration; - -#if NS_BLOCKS_AVAILABLE - -+ (PRTweenOperation *)lerp:(id)object - property:(NSString *)property - from:(CGSize)from - to:(CGSize)to - duration:(CGFloat)duration - timingFunction:(PRTweenTimingFunction)timingFunction - updateBlock:(PRTweenUpdateBlock)updateBlock - completeBlock:(PRTweenCompleteBlock)completeBlock; - -//+ (PRTweenOperation *)lerp:(id)object -// property:(NSString *)property -// from:(CGSize)from -// to:(CGSize)to -// duration:(CGFloat)duration -// delay:(CGFloat)delay -// timingFunction:(PRTweenTimingFunction)timingFunction -// updateBlock:(PRTweenUpdateBlock)updateBlock -// completeBlock:(PRTweenCompleteBlock)completeBlock; - -#endif -@end - -@interface PRTween : NSObject { - NSMutableArray *tweenOperations; - NSMutableArray *expiredTweenOperations; - NSTimer *timer; - CGFloat timeOffset; - - PRTweenTimingFunction defaultTimingFunction; - BOOL useBuiltInAnimationsWhenPossible; -} - -@property(nonatomic, readonly) CGFloat timeOffset; -@property(nonatomic, assign) PRTweenTimingFunction defaultTimingFunction; -@property(nonatomic, assign) BOOL useBuiltInAnimationsWhenPossible; - -+ (PRTween *)sharedInstance; - -+ (PRTweenOperation *)tween:(id)object - property:(NSString *)property - from:(CGFloat)from - to:(CGFloat)to - duration:(CGFloat)duration - timingFunction:(PRTweenTimingFunction)timingFunction - target:(NSObject *)target - completeSelector:(SEL)selector; - -+ (PRTweenOperation *)tween:(CGFloat *)ref - from:(CGFloat)from - to:(CGFloat)to - duration:(CGFloat)duration - timingFunction:(PRTweenTimingFunction)timingFunction - target:(NSObject *)target - completeSelector:(SEL)selector; - -+ (PRTweenOperation *)tween:(CGFloat *)ref - from:(CGFloat)from - to:(CGFloat)to - duration:(CGFloat)duration - delay:(CGFloat)delay - timingFunction:(PRTweenTimingFunction)timingFunction - target:(NSObject *)target - completeSelector:(SEL)selector; - -+ (PRTweenOperation *)tween:(id)object - property:(NSString *)property - from:(CGFloat)from - to:(CGFloat)to - duration:(CGFloat)duration; - -+ (PRTweenOperation *)tween:(CGFloat *)ref - from:(CGFloat)from - to:(CGFloat)to - duration:(CGFloat)duration; - -+ (PRTweenOperation *)lerp:(id)object - property:(NSString *)property - period:(PRTweenLerpPeriod *)period - timingFunction:(PRTweenTimingFunction)timingFunction - target:(NSObject *)target - completeSelector:(SEL)selector; - -- (PRTweenOperation *)addTweenOperation:(PRTweenOperation *)operation; - -- (PRTweenOperation *)addTweenPeriod:(PRTweenPeriod *)period - target:(NSObject *)target - selector:(SEL)selector; - -- (PRTweenOperation *)addTweenPeriod:(PRTweenPeriod *)period - target:(NSObject *)target - selector:(SEL)selector - timingFunction:(PRTweenTimingFunction)timingFunction; - -- (void)removeTweenOperation:(PRTweenOperation *)tweenOperation; - -- (void)removeAllTweenOperations; - -#if NS_BLOCKS_AVAILABLE - -+ (PRTweenOperation *)tween:(id)object - property:(NSString *)property - from:(CGFloat)from - to:(CGFloat)to - duration:(CGFloat)duration - timingFunction:(PRTweenTimingFunction)timingFunction - updateBlock:(PRTweenUpdateBlock)updateBlock - completeBlock:(PRTweenCompleteBlock)completeBlock; - -+ (PRTweenOperation *)tween:(id)object - property:(NSString *)property - from:(CGFloat)from - to:(CGFloat)to - duration:(CGFloat)duration - delay:(CGFloat)delay - timingFunction:(PRTweenTimingFunction)timingFunction - updateBlock:(PRTweenUpdateBlock)updateBlock - completeBlock:(PRTweenCompleteBlock)completeBlock; - -+ (PRTweenOperation *)tween:(CGFloat *)ref - from:(CGFloat)from to:(CGFloat)to - duration:(CGFloat)duration - timingFunction:(PRTweenTimingFunction)timingFunction - updateBlock:(PRTweenUpdateBlock)updateBlock - completeBlock:(PRTweenCompleteBlock)completeBlock; - -+ (PRTweenOperation *)tween:(CGFloat *)ref - from:(CGFloat)from - to:(CGFloat)to - duration:(CGFloat)duration - delay:(CGFloat)delay - timingFunction:(PRTweenTimingFunction)timingFunction - updateBlock:(PRTweenUpdateBlock)updateBlock - completeBlock:(PRTweenCompleteBlock)completeBlock; - -+ (PRTweenOperation *)lerp:(id)object - property:(NSString *)property - period:(PRTweenLerpPeriod *)period - timingFunction:(PRTweenTimingFunction)timingFunction - updateBlock:(PRTweenUpdateBlock)updateBlock - completeBlock:(PRTweenCompleteBlock)completeBlock; - -- (PRTweenOperation *)addTweenPeriod:(PRTweenPeriod *)period - updateBlock:(PRTweenUpdateBlock)updateBlock - completionBlock:(PRTweenCompleteBlock)completeBlock; - -- (PRTweenOperation *)addTweenPeriod:(PRTweenPeriod *)period - updateBlock:(PRTweenUpdateBlock)updateBlock - completionBlock:(PRTweenCompleteBlock)completionBlock - timingFunction:(PRTweenTimingFunction)timingFunction; - -#endif - -@end diff --git a/KACircleProgressView/External/PRTween/lib/PRTween.m b/KACircleProgressView/External/PRTween/lib/PRTween.m deleted file mode 100755 index b654374..0000000 --- a/KACircleProgressView/External/PRTween/lib/PRTween.m +++ /dev/null @@ -1,1175 +0,0 @@ - -#import "PRTween.h" - -#define kPRTweenFramerate 1.0/60 - -@implementation PRTweenPeriod -@synthesize startValue; -@synthesize endValue; -@synthesize tweenedValue; -@synthesize duration; -@synthesize delay; -@synthesize startOffset; - -+ (id)periodWithStartValue:(CGFloat)aStartValue - endValue:(CGFloat)anEndValue - duration:(CGFloat)duration { - - PRTweenPeriod *period = [PRTweenPeriod new]; - - period.startValue = period.tweenedValue = aStartValue; - period.endValue = anEndValue; - period.duration = duration; - period.startOffset = [[PRTween sharedInstance] timeOffset]; - - return period; -} - -+ (id)periodWithStartValue:(CGFloat)aStartValue - endValue:(CGFloat)anEndValue - duration:(CGFloat)duration - delay:(CGFloat)delay { - - PRTweenPeriod *period = [PRTweenPeriod new]; - - period.startValue = period.tweenedValue = aStartValue; - period.endValue = anEndValue; - period.duration = duration; - period.delay = delay; - period.startOffset = [[PRTween sharedInstance] timeOffset]; - - return period; -} - -@end - -@implementation PRTweenLerpPeriod -@synthesize startLerp; -@synthesize endLerp; -@synthesize tweenedLerp; - -+ (id)periodWithStartValue:(NSValue *)aStartValue - endValue:(NSValue *)anEndValue - duration:(CGFloat)duration { - - PRTweenLerpPeriod *period = [[self class] new]; - period.startLerp = aStartValue; - period.tweenedLerp = aStartValue; - period.endLerp = anEndValue; - period.duration = duration; - period.startOffset = [[PRTween sharedInstance] timeOffset]; - - return period; -} - -+ (id)periodWithStartValue:(NSValue *)aStartValue - endValue:(NSValue *)anEndValue - duration:(CGFloat)duration - delay:(CGFloat)delay { - - PRTweenLerpPeriod *period = [[self class] new]; - period.startLerp = aStartValue; - period.tweenedLerp = aStartValue; - period.endLerp = anEndValue; - period.duration = duration; - period.delay = delay; - period.startOffset = [[PRTween sharedInstance] timeOffset]; - - return period; -} - -@end - -@implementation PRTweenCGPointLerpPeriod - -+ (id)periodWithStartCGPoint:(CGPoint)aStartPoint - endCGPoint:(CGPoint)anEndPoint - duration:(CGFloat)duration { - - return [PRTweenCGPointLerpPeriod periodWithStartValue:[NSValue valueWithCGPoint:aStartPoint] endValue:[NSValue valueWithCGPoint:anEndPoint] duration:duration]; -} - -- (CGPoint)startCGPoint { - return [self.startLerp CGPointValue]; -} - -- (CGPoint)tweenedCGPoint { - return [self.tweenedLerp CGPointValue]; -} - -- (CGPoint)endCGPoint { - return [self.endLerp CGPointValue]; -} - -- (NSValue *)tweenedValueForProgress:(CGFloat)progress { - - CGPoint startPoint = self.startCGPoint; - CGPoint endPoint = self.endCGPoint; - CGPoint distance = CGPointMake(endPoint.x - startPoint.x, endPoint.y - startPoint.y); - CGPoint tweenedPoint = CGPointMake(startPoint.x + distance.x * progress, startPoint.y + distance.y * progress); - - return [NSValue valueWithCGPoint:tweenedPoint]; - -} - -- (void)setProgress:(CGFloat)progress { - self.tweenedLerp = [self tweenedValueForProgress:progress]; -} - -@end - -@implementation PRTweenCGRectLerpPeriod - -+ (id)periodWithStartCGRect:(CGRect)aStartRect - endCGRect:(CGRect)anEndRect - duration:(CGFloat)duration { - - return [PRTweenCGRectLerpPeriod periodWithStartValue:[NSValue valueWithCGRect:aStartRect] endValue:[NSValue valueWithCGRect:anEndRect] duration:duration]; -} - -- (CGRect)startCGRect { - return [self.startLerp CGRectValue]; -} - -- (CGRect)tweenedCGRect { - return [self.tweenedLerp CGRectValue]; -} - -- (CGRect)endCGRect { - return [self.endLerp CGRectValue]; -} - -- (NSValue *)tweenedValueForProgress:(CGFloat)progress { - - CGRect startRect = self.startCGRect; - CGRect endRect = self.endCGRect; - CGRect distance = CGRectMake(endRect.origin.x - startRect.origin.x, endRect.origin.y - startRect.origin.y, endRect.size.width - startRect.size.width, endRect.size.height - startRect.size.height); - CGRect tweenedRect = CGRectMake(startRect.origin.x + distance.origin.x * progress, startRect.origin.y + distance.origin.y * progress, startRect.size.width + distance.size.width * progress, startRect.size.height + distance.size.height * progress); - - return [NSValue valueWithCGRect:tweenedRect]; - -} - -- (void)setProgress:(CGFloat)progress { - self.tweenedLerp = [self tweenedValueForProgress:progress]; -} - -@end - -@implementation PRTweenCGSizeLerpPeriod - -+ (id)periodWithStartCGSize:(CGSize)aStartSize - endCGSize:(CGSize)anEndSize - duration:(CGFloat)duration { - - return [PRTweenCGRectLerpPeriod periodWithStartValue:[NSValue valueWithCGSize:aStartSize] endValue:[NSValue valueWithCGSize:anEndSize] duration:duration]; -} - -+ (id)periodWithStartCGSize:(CGSize)aStartSize - endCGSize:(CGSize)anEndSize - duration:(CGFloat)duration - delay:(CGFloat)delay { - - return [PRTweenCGRectLerpPeriod periodWithStartValue:[NSValue valueWithCGSize:aStartSize] endValue:[NSValue valueWithCGSize:anEndSize] duration:duration delay:delay]; -} - -- (CGSize)startCGSize { - return [self.startLerp CGSizeValue]; -} - -- (CGSize)tweenedCGSize { - return [self.tweenedLerp CGSizeValue]; -} - -- (CGSize)endCGSize { - return [self.endLerp CGSizeValue]; -} - -- (NSValue *)tweenedValueForProgress:(CGFloat)progress { - - CGSize startSize = self.startCGSize; - CGSize endSize = self.endCGSize; - CGSize distance = CGSizeMake(endSize.width - startSize.width, endSize.height - startSize.height); - CGSize tweenedSize = CGSizeMake(startSize.width + distance.width * progress, startSize.height + distance.height * progress); - return [NSValue valueWithCGSize:tweenedSize]; - -} - -- (void)setProgress:(CGFloat)progress { - self.tweenedLerp = [self tweenedValueForProgress:progress]; -} - -@end - -@interface PRTweenOperation () -@property(nonatomic) BOOL canUseBuiltAnimation; -@end - -@implementation PRTweenOperation -@synthesize period; -@synthesize target; -@synthesize updateSelector; -@synthesize completeSelector; -@synthesize timingFunction; -@synthesize boundRef; -@synthesize boundObject; -@synthesize boundGetter; -@synthesize boundSetter; -@synthesize canUseBuiltAnimation; -@synthesize override; -@synthesize wasPreempted; -@synthesize observers; - -#if NS_BLOCKS_AVAILABLE -@synthesize updateBlock; -@synthesize completeBlock; -#endif - -@end - -@implementation PRTweenCGPointLerp - -+ (PRTweenOperation *)lerp:(id)object - property:(NSString *)property - from:(CGPoint)from - to:(CGPoint)to - duration:(CGFloat)duration - timingFunction:(PRTweenTimingFunction)timingFunction - target:(NSObject *)target - completeSelector:(SEL)selector { - - return [PRTween lerp:object - property:property - period:[PRTweenCGPointLerpPeriod - periodWithStartCGPoint:from - endCGPoint:to - duration:duration] - timingFunction:timingFunction - target:target - completeSelector:selector]; -} - -+ (PRTweenOperation *)lerp:(id)object - property:(NSString *)property - from:(CGPoint)from - to:(CGPoint)to - duration:(CGFloat)duration - delay:(CGFloat)delay - timingFunction:(PRTweenTimingFunction)timingFunction - target:(NSObject *)target - completeSelector:(SEL)selector { - - PRTweenCGPointLerpPeriod *period = [PRTweenCGPointLerpPeriod periodWithStartCGPoint:from endCGPoint:to duration:duration]; - period.delay = delay; - - return [PRTween lerp:object - property:property - period:period - timingFunction:timingFunction - target:target - completeSelector:selector]; -} - -+ (PRTweenOperation *)lerp:(id)object - property:(NSString *)property - from:(CGPoint)from - to:(CGPoint)to - duration:(CGFloat)duration { - - return [PRTweenCGPointLerp - lerp:object - property:property - from:from - to:to - duration:duration - timingFunction:NULL target:nil completeSelector:NULL]; -} - -#if NS_BLOCKS_AVAILABLE - -+ (PRTweenOperation *)lerp:(id)object - property:(NSString *)property - from:(CGPoint)from - to:(CGPoint)to - duration:(CGFloat)duration - timingFunction:(PRTweenTimingFunction)timingFunction - updateBlock:(PRTweenUpdateBlock)updateBlock - completeBlock:(PRTweenCompleteBlock)completeBlock { - - return [PRTween lerp:object - property:property - period:[PRTweenCGPointLerpPeriod - periodWithStartCGPoint:from - endCGPoint:to - duration:duration] - timingFunction:timingFunction - updateBlock:updateBlock - completeBlock:completeBlock]; -} - -+ (PRTweenOperation *)lerp:(id)object - property:(NSString *)property - from:(CGPoint)from - to:(CGPoint)to - duration:(CGFloat)duration - delay:(CGFloat)delay - timingFunction:(PRTweenTimingFunction)timingFunction - updateBlock:(PRTweenUpdateBlock)updateBlock - completeBlock:(PRTweenCompleteBlock)completeBlock { - - PRTweenCGPointLerpPeriod *period = [PRTweenCGPointLerpPeriod periodWithStartCGPoint:from endCGPoint:to duration:duration]; - [period setDelay:delay]; - - return [PRTween lerp:object property:property period:period timingFunction:timingFunction updateBlock:updateBlock completeBlock:completeBlock]; -} - -#endif - -@end - -@implementation PRTweenCGRectLerp - -+ (PRTweenOperation *)lerp:(id)object - property:(NSString *)property - from:(CGRect)from - to:(CGRect)to - duration:(CGFloat)duration - timingFunction:(PRTweenTimingFunction)timingFunction - target:(NSObject *)target - completeSelector:(SEL)selector { - - return [PRTween lerp:object - property:property - period:[PRTweenCGRectLerpPeriod - periodWithStartCGRect:from - endCGRect:to - duration:duration] - timingFunction:timingFunction - target:target - completeSelector:selector]; -} - -+ (PRTweenOperation *)lerp:(id)object - property:(NSString *)property - from:(CGRect)from - to:(CGRect)to - duration:(CGFloat)duration - delay:(CGFloat)delay - timingFunction:(PRTweenTimingFunction)timingFunction - target:(NSObject *)target - completeSelector:(SEL)selector { - - PRTweenCGRectLerpPeriod *period = [PRTweenCGRectLerpPeriod periodWithStartCGRect:from - endCGRect:to - duration:duration]; - period.delay = delay; - return [PRTween lerp:object - property:property - period:period - timingFunction:timingFunction - target:target - completeSelector:selector]; -} - -+ (PRTweenOperation *)lerp:(id)object - property:(NSString *)property - from:(CGRect)from - to:(CGRect)to - duration:(CGFloat)duration { - - return [PRTweenCGRectLerp lerp:object - property:property - from:from - to:to - duration:duration - timingFunction:NULL target:nil completeSelector:NULL]; -} - -#if NS_BLOCKS_AVAILABLE - -+ (PRTweenOperation *)lerp:(id)object - property:(NSString *)property - from:(CGRect)from - to:(CGRect)to - duration:(CGFloat)duration - timingFunction:(PRTweenTimingFunction)timingFunction - updateBlock:(PRTweenUpdateBlock)updateBlock - completeBlock:(PRTweenCompleteBlock)completeBlock { - return [PRTween lerp:object property:property period:[PRTweenCGRectLerpPeriod periodWithStartCGRect:from endCGRect:to duration:duration] timingFunction:timingFunction updateBlock:updateBlock completeBlock:completeBlock]; -} - -+ (PRTweenOperation *)lerp:(id)object - property:(NSString *)property - from:(CGRect)from - to:(CGRect)to - duration:(CGFloat)duration - delay:(CGFloat)delay - timingFunction:(PRTweenTimingFunction)timingFunction - updateBlock:(PRTweenUpdateBlock)updateBlock - completeBlock:(PRTweenCompleteBlock)completeBlock { - - PRTweenCGRectLerpPeriod *period = [PRTweenCGRectLerpPeriod periodWithStartCGRect:from endCGRect:to duration:duration]; - [period setDelay:delay]; - - return [PRTween lerp:object property:property period:period timingFunction:timingFunction updateBlock:updateBlock completeBlock:completeBlock]; -} - -#endif - -@end - -@implementation PRTweenCGSizeLerp - -+ (PRTweenOperation *)lerp:(id)object - property:(NSString *)property - from:(CGSize)from - to:(CGSize)to - duration:(CGFloat)duration - timingFunction:(PRTweenTimingFunction)timingFunction - target:(NSObject *)target - completeSelector:(SEL)selector { - - return [PRTween lerp:object - property:property - period:[PRTweenCGSizeLerpPeriod - periodWithStartCGSize:from - endCGSize:to - duration:duration] - timingFunction:timingFunction - target:target - completeSelector:selector]; -} - -+ (PRTweenOperation *)lerp:(id)object - property:(NSString *)property - from:(CGSize)from - to:(CGSize)to - duration:(CGFloat)duration - delay:(CGFloat)delay - timingFunction:(PRTweenTimingFunction)timingFunction - target:(NSObject *)target - completeSelector:(SEL)selector { - - PRTweenCGPointLerpPeriod *period = [PRTweenCGSizeLerpPeriod periodWithStartCGSize:from - endCGSize:to - duration:duration]; - period.delay = delay; - return [PRTween lerp:object - property:property - period:period - timingFunction:timingFunction - target:target - completeSelector:selector]; -} - -+ (PRTweenOperation *)lerp:(id)object - property:(NSString *)property - from:(CGSize)from - to:(CGSize)to - duration:(CGFloat)duration { - - return [PRTweenCGSizeLerp lerp:object - property:property - from:from - to:to - duration:duration - timingFunction:NULL target:nil completeSelector:NULL]; -} - -#if NS_BLOCKS_AVAILABLE - -+ (PRTweenOperation *)lerp:(id)object - property:(NSString *)property - from:(CGSize)from - to:(CGSize)to - duration:(CGFloat)duration - timingFunction:(PRTweenTimingFunction)timingFunction - updateBlock:(PRTweenUpdateBlock)updateBlock - completeBlock:(PRTweenCompleteBlock)completeBlock { - - return [PRTween lerp:object - property:property - period:[PRTweenCGSizeLerpPeriod - periodWithStartCGSize:from - endCGSize:to - duration:duration] - timingFunction:timingFunction - updateBlock:updateBlock - completeBlock:completeBlock]; -} - -#endif - -@end - -@interface PRTween () -+ (SEL)setterFromProperty:(NSString *)property; - -- (void)update; -@end - -static PRTween *instance = nil; -static NSArray *animationSelectorsForCoreAnimation = nil; -static NSArray *animationSelectorsForUIView = nil; - -@implementation PRTween -@synthesize timeOffset; -@synthesize defaultTimingFunction; -@synthesize useBuiltInAnimationsWhenPossible; - -+ (PRTween *)sharedInstance { - if (instance == nil) { - instance = [[PRTween alloc] init]; - instance.useBuiltInAnimationsWhenPossible = YES; - } - return instance; -} - -+ (PRTweenOperation *)tween:(id)object - property:(NSString *)property - from:(CGFloat)from - to:(CGFloat)to - duration:(CGFloat)duration - timingFunction:(PRTweenTimingFunction)timingFunction - target:(NSObject *)target - completeSelector:(SEL)selector { - - PRTweenPeriod *period = [PRTweenPeriod periodWithStartValue:from - endValue:to - duration:duration]; - PRTweenOperation *operation = [PRTweenOperation new]; - operation.period = period; - operation.timingFunction = timingFunction; - operation.target = target; - operation.completeSelector = selector; - operation.boundObject = object; - operation.boundGetter = NSSelectorFromString([NSString stringWithFormat:@"%@", property]); - operation.boundSetter = [PRTween setterFromProperty:property]; - operation.wasPreempted = NO; - [self addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedValue" observerOptions:PRTweenHasTweenedValueObserver operation:operation]; - - [[PRTween sharedInstance] performSelector:@selector(addTweenOperation:) withObject:operation afterDelay:0]; - return operation; - -} - -+ (PRTweenOperation *)tween:(CGFloat *)ref - from:(CGFloat)from - to:(CGFloat)to - duration:(CGFloat)duration - timingFunction:(PRTweenTimingFunction)timingFunction - target:(NSObject *)target - completeSelector:(SEL)selector { - - PRTweenPeriod *period = [PRTweenPeriod periodWithStartValue:from - endValue:to - duration:duration]; - PRTweenOperation *operation = [PRTweenOperation new]; - operation.period = period; - operation.timingFunction = timingFunction; - operation.target = target; - operation.completeSelector = selector; - operation.boundRef = ref; - operation.wasPreempted = NO; - [self addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedValue" observerOptions:PRTweenHasTweenedValueObserver operation:operation]; - - [[PRTween sharedInstance] performSelector:@selector(addTweenOperation:) withObject:operation afterDelay:0 inModes:[NSArray arrayWithObject:NSRunLoopCommonModes]]; - return operation; - -} - -+ (PRTweenOperation *)tween:(CGFloat *)ref - from:(CGFloat)from - to:(CGFloat)to - duration:(CGFloat)duration - delay:(CGFloat)delay - timingFunction:(PRTweenTimingFunction)timingFunction - target:(NSObject *)target - completeSelector:(SEL)selector { - - PRTweenPeriod *period = [PRTweenPeriod periodWithStartValue:from - endValue:to - duration:duration - delay:delay]; - PRTweenOperation *operation = [PRTweenOperation new]; - operation.period = period; - operation.timingFunction = timingFunction; - operation.target = target; - operation.completeSelector = selector; - operation.boundRef = ref; - operation.wasPreempted = NO; - [self addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedValue" observerOptions:PRTweenHasTweenedValueObserver operation:operation]; - - [[PRTween sharedInstance] performSelector:@selector(addTweenOperation:) withObject:operation afterDelay:0 inModes:[NSArray arrayWithObject:NSRunLoopCommonModes]]; - return operation; - -} - -+ (PRTweenOperation *)tween:(id)object - property:(NSString *)property - from:(CGFloat)from - to:(CGFloat)to - duration:(CGFloat)duration { - - return [PRTween tween:object - property:property - from:from - to:to - duration:duration - timingFunction:NULL target:nil completeSelector:NULL]; -} - -+ (PRTweenOperation *)tween:(CGFloat *)ref - from:(CGFloat)from - to:(CGFloat)to - duration:(CGFloat)duration { - - return [PRTween tween:ref - from:from - to:to - duration:duration - timingFunction:NULL target:nil completeSelector:NULL]; -} - -+ (PRTweenOperation *)lerp:(id)object - property:(NSString *)property - period:(PRTweenLerpPeriod *)period - timingFunction:(PRTweenTimingFunction)timingFunction - target:(NSObject *)target - completeSelector:(SEL)selector { - - //PRTweenPeriod *period = [PRTweenLerpPeriod periodWithStartValue:from endValue:to duration:duration]; - PRTweenOperation *operation = [PRTweenOperation new]; - operation.period = period; - operation.timingFunction = timingFunction; - operation.target = target; - operation.completeSelector = selector; - operation.boundObject = object; - operation.boundGetter = NSSelectorFromString([NSString stringWithFormat:@"%@", property]); - operation.boundSetter = [PRTween setterFromProperty:property]; - operation.wasPreempted = NO; - [self addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedLerp" observerOptions:PRTweenHasTweenedLerpObserver operation:operation]; - - [[PRTween sharedInstance] performSelector:@selector(addTweenOperation:) withObject:operation afterDelay:0 inModes:[NSArray arrayWithObject:NSRunLoopCommonModes]]; - return operation; - -} - -#if NS_BLOCKS_AVAILABLE - -+ (PRTweenOperation *)tween:(id)object - property:(NSString *)property - from:(CGFloat)from - to:(CGFloat)to - duration:(CGFloat)duration - timingFunction:(PRTweenTimingFunction)timingFunction - updateBlock:(PRTweenUpdateBlock)updateBlock - completeBlock:(PRTweenCompleteBlock)completeBlock { - - PRTweenPeriod *period = [PRTweenPeriod periodWithStartValue:from - endValue:to - duration:duration]; - PRTweenOperation *operation = [PRTweenOperation new]; - operation.period = period; - operation.timingFunction = timingFunction; - operation.updateBlock = updateBlock; - operation.completeBlock = completeBlock; - operation.boundObject = object; - operation.boundGetter = NSSelectorFromString([NSString stringWithFormat:@"%@", property]); - operation.boundSetter = [PRTween setterFromProperty:property]; - operation.wasPreempted = NO; - [self addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedValue" observerOptions:PRTweenHasTweenedValueObserver operation:operation]; - - [[PRTween sharedInstance] performSelector:@selector(addTweenOperation:) withObject:operation afterDelay:0]; - return operation; - -} - -+ (PRTweenOperation *)tween:(id)object - property:(NSString *)property - from:(CGFloat)from - to:(CGFloat)to - duration:(CGFloat)duration - delay:(CGFloat)delay - timingFunction:(PRTweenTimingFunction)timingFunction - updateBlock:(PRTweenUpdateBlock)updateBlock - completeBlock:(PRTweenCompleteBlock)completeBlock { - - PRTweenPeriod *period = [PRTweenPeriod periodWithStartValue:from - endValue:to - duration:duration - delay:delay]; - PRTweenOperation *operation = [PRTweenOperation new]; - operation.period = period; - operation.timingFunction = timingFunction; - operation.updateBlock = updateBlock; - operation.completeBlock = completeBlock; - operation.boundObject = object; - operation.boundGetter = NSSelectorFromString([NSString stringWithFormat:@"%@", property]); - operation.boundSetter = [PRTween setterFromProperty:property]; - operation.wasPreempted = NO; - [self addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedValue" observerOptions:PRTweenHasTweenedValueObserver operation:operation]; - - [[PRTween sharedInstance] performSelector:@selector(addTweenOperation:) withObject:operation afterDelay:0]; - return operation; - -} - -+ (PRTweenOperation *)tween:(CGFloat *)ref - from:(CGFloat)from - to:(CGFloat)to - duration:(CGFloat)duration - timingFunction:(PRTweenTimingFunction)timingFunction - updateBlock:(PRTweenUpdateBlock)updateBlock - completeBlock:(PRTweenCompleteBlock)completeBlock { - - PRTweenPeriod *period = [PRTweenPeriod periodWithStartValue:from - endValue:to - duration:duration]; - PRTweenOperation *operation = [PRTweenOperation new]; - operation.period = period; - operation.timingFunction = timingFunction; - operation.updateBlock = updateBlock; - operation.completeBlock = completeBlock; - operation.boundRef = ref; - operation.wasPreempted = NO; - [self addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedValue" observerOptions:PRTweenHasTweenedValueObserver operation:operation]; - - [[PRTween sharedInstance] performSelector:@selector(addTweenOperation:) withObject:operation afterDelay:0 inModes:[NSArray arrayWithObject:NSRunLoopCommonModes]]; - return operation; - -} - -+ (PRTweenOperation *)tween:(CGFloat *)ref - from:(CGFloat)from - to:(CGFloat)to - duration:(CGFloat)duration - delay:(CGFloat)delay - timingFunction:(PRTweenTimingFunction)timingFunction - updateBlock:(PRTweenUpdateBlock)updateBlock - completeBlock:(PRTweenCompleteBlock)completeBlock { - - PRTweenPeriod *period = [PRTweenPeriod periodWithStartValue:from - endValue:to - duration:duration - delay:delay]; - PRTweenOperation *operation = [PRTweenOperation new]; - operation.period = period; - operation.timingFunction = timingFunction; - operation.updateBlock = updateBlock; - operation.completeBlock = completeBlock; - operation.boundRef = ref; - operation.wasPreempted = NO; - [self addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedValue" observerOptions:PRTweenHasTweenedValueObserver operation:operation]; - - [[PRTween sharedInstance] performSelector:@selector(addTweenOperation:) withObject:operation afterDelay:0 inModes:[NSArray arrayWithObject:NSRunLoopCommonModes]]; - return operation; - -} - -+ (PRTweenOperation *)lerp:(id)object - property:(NSString *)property - period:(PRTweenLerpPeriod *)period - timingFunction:(PRTweenTimingFunction)timingFunction - updateBlock:(PRTweenUpdateBlock)updateBlock - completeBlock:(PRTweenCompleteBlock)completeBlock { - - //PRTweenPeriod *period = [PRTweenLerpPeriod periodWithStartValue:from endValue:to duration:duration]; - PRTweenOperation *operation = [PRTweenOperation new]; - operation.period = period; - operation.timingFunction = timingFunction; - operation.updateBlock = updateBlock; - operation.completeBlock = completeBlock; - operation.boundObject = object; - operation.boundGetter = NSSelectorFromString([NSString stringWithFormat:@"%@", property]); - operation.boundSetter = [PRTween setterFromProperty:property]; - operation.wasPreempted = NO; - [self addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedLerp" observerOptions:PRTweenHasTweenedLerpObserver operation:operation]; - - [[PRTween sharedInstance] performSelector:@selector(addTweenOperation:) withObject:operation afterDelay:0 inModes:[NSArray arrayWithObject:NSRunLoopCommonModes]]; - return operation; - -} - -#endif - -+ (void)addObserver:(NSObject *)observer - forKeyPath:(NSString *)keyPath - observerOptions:(PRTweenHasTweenedObserverOptions)observerOptions - operation:(PRTweenOperation *)operation { - - [operation addObserver:observer forKeyPath:keyPath options:NSKeyValueObservingOptionNew context:NULL]; - operation.observers = operation.observers | observerOptions; -} - -- (void)observeValueForKeyPath:(NSString *)keyPath - ofObject:(id)object - change:(NSDictionary *)change - context:(void *)context { - - PRTweenOperation *operation = (PRTweenOperation *) object; - - if ([operation.period isKindOfClass:[PRTweenLerpPeriod class]]) { - PRTweenLerpPeriod *lerpPeriod = (PRTweenLerpPeriod *) operation.period; - - NSUInteger bufferSize = 0; - NSGetSizeAndAlignment([lerpPeriod.tweenedLerp objCType], &bufferSize, NULL); - void *tweenedValue = malloc(bufferSize); - [lerpPeriod.tweenedLerp getValue:tweenedValue]; - - if (operation.boundObject && [operation.boundObject respondsToSelector:operation.boundGetter] && [operation.boundObject respondsToSelector:operation.boundSetter]) { - NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[[operation.boundObject class] - instanceMethodSignatureForSelector:operation.boundSetter]]; - [invocation setTarget:operation.boundObject]; - [invocation setSelector:operation.boundSetter]; - [invocation setArgument:tweenedValue atIndex:2]; - [invocation invoke]; - } - - free(tweenedValue); - - } else { - - CGFloat tweenedValue = operation.period.tweenedValue; - - if (operation.boundObject && [operation.boundObject respondsToSelector:operation.boundGetter] && [operation.boundObject respondsToSelector:operation.boundSetter]) { - NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[[operation.boundObject class] - instanceMethodSignatureForSelector:operation.boundSetter]]; - [invocation setTarget:operation.boundObject]; - [invocation setSelector:operation.boundSetter]; - [invocation setArgument:&tweenedValue atIndex:2]; - [invocation invoke]; - } else if (operation.boundRef) { - *operation.boundRef = tweenedValue; - } - - } - -} - -- (id)init { - self = [super init]; - if (self != nil) { - tweenOperations = [[NSMutableArray alloc] init]; - expiredTweenOperations = [[NSMutableArray alloc] init]; - timeOffset = 0; - if (timer == nil) { - timer = [NSTimer scheduledTimerWithTimeInterval:kPRTweenFramerate target:self selector:@selector(update) userInfo:nil repeats:YES]; - [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes]; - } - self.defaultTimingFunction = &PRTweenTimingFunctionQuadInOut; - } - return self; -} - -- (PRTweenOperation *)addTweenOperation:(PRTweenOperation *)operation { - - if (useBuiltInAnimationsWhenPossible && !operation.override) { - - if (animationSelectorsForCoreAnimation == nil) { - animationSelectorsForCoreAnimation = [[NSArray alloc] initWithObjects: - @"setBounds:", // CGRect - @"setPosition:", // CGPoint - @"setZPosition:", // CGFloat - @"setAnchorPoint:", // CGPoint - @"setAnchorPointZ:", // CGFloat - //@"setTransform:", // CATransform3D - //@"setSublayerTransform:", // CATransform3D - @"setFrame:", // CGRect - @"setContentsRect" // CGRect - @"setContentsScale:", // CGFloat - @"setContentsCenter:", // CGPoint - //@"setBackgroundColor:", // CGColorRef - @"setCornerRadius:", // CGFloat - @"setBorderWidth:", // CGFloat - @"setOpacity:", // CGFloat - //@"setShadowColor:", // CGColorRef - @"setShadowOpacity:", // CGFloat - @"setShadowOffset:", // CGSize - @"setShadowRadius:", // CGFloat - //@"setShadowPath:", - nil]; - } - - if (animationSelectorsForUIView == nil) { - animationSelectorsForUIView = [[NSArray alloc] initWithObjects: - @"setFrame:", // CGRect - @"setBounds:", // CGRect - @"setCenter:", // CGPoint - @"setTransform:", // CGAffineTransform - @"setAlpha:", // CGFloat - //@"setBackgroundColor:", // UIColor - @"setContentStretch:", // CGRect - nil]; - } - - if (operation.boundSetter && operation.boundObject && !(operation.timingFunction == &PRTweenTimingFunctionCADefault || - operation.timingFunction == &PRTweenTimingFunctionCAEaseIn || - operation.timingFunction == &PRTweenTimingFunctionCAEaseOut || - operation.timingFunction == &PRTweenTimingFunctionCAEaseInOut || - operation.timingFunction == &PRTweenTimingFunctionCALinear || - operation.timingFunction == &PRTweenTimingFunctionUIViewEaseIn || - operation.timingFunction == &PRTweenTimingFunctionUIViewEaseOut || - operation.timingFunction == &PRTweenTimingFunctionUIViewEaseInOut || - operation.timingFunction == &PRTweenTimingFunctionUIViewLinear || - operation.timingFunction == NULL)) { - goto complete; - } - - - if (operation.boundSetter && operation.boundObject && [operation.boundObject isKindOfClass:[CALayer class]]) { - for (NSString *selector in animationSelectorsForCoreAnimation) { - NSString *setter = NSStringFromSelector(operation.boundSetter); - if ([selector isEqualToString:setter]) { - NSLog(@"Using Core Animation for %@", NSStringFromSelector(operation.boundSetter)); - operation.canUseBuiltAnimation = YES; - - NSString *propertyUnformatted = [selector stringByReplacingCharactersInRange:NSMakeRange(0, 3) withString:@""]; - NSString *propertyFormatted = [[propertyUnformatted stringByReplacingCharactersInRange:NSMakeRange(0, 1) withString:[[propertyUnformatted substringToIndex:1] - lowercaseString]] substringToIndex:[propertyUnformatted length] - 1]; - //NSLog(@"%@", propertyFormatted); - CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:propertyFormatted]; - animation.duration = operation.period.duration; - - if (![operation.period isKindOfClass:[PRTweenLerpPeriod class]] && ![operation.period conformsToProtocol:@protocol(PRTweenLerpPeriod)]) { - animation.fromValue = [NSNumber numberWithFloat:operation.period.startValue]; - animation.toValue = [NSNumber numberWithFloat:operation.period.endValue]; - } else { - PRTweenLerpPeriod *period = (PRTweenLerpPeriod *) operation.period; - animation.fromValue = period.startLerp; - animation.toValue = period.endLerp; - } - - if (operation.timingFunction == &PRTweenTimingFunctionCAEaseIn) { - animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]; - } else if (operation.timingFunction == &PRTweenTimingFunctionCAEaseOut) { - animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]; - } else if (operation.timingFunction == &PRTweenTimingFunctionCAEaseInOut) { - animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; - } else if (operation.timingFunction == &PRTweenTimingFunctionCALinear) { - animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; - } else { - animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault]; - } - - [operation.boundObject setValue:animation.toValue forKeyPath:propertyFormatted]; - [operation.boundObject addAnimation:animation forKey:@"PRTweenCAAnimation"]; - - goto complete; - } - } - } else if (operation.boundSetter && operation.boundObject && [operation.boundObject isKindOfClass:[UIView class]]) { - for (NSString *selector in animationSelectorsForUIView) { - NSString *setter = NSStringFromSelector(operation.boundSetter); - if ([selector isEqualToString:setter]) { - NSLog(@"Using UIView Animation for %@", NSStringFromSelector(operation.boundSetter)); - operation.canUseBuiltAnimation = YES; - - NSString *propertyUnformatted = [selector stringByReplacingCharactersInRange:NSMakeRange(0, 3) withString:@""]; - NSString *propertyFormatted = [[propertyUnformatted stringByReplacingCharactersInRange:NSMakeRange(0, 1) withString:[[propertyUnformatted substringToIndex:1] - lowercaseString]] substringToIndex:[propertyUnformatted length] - 1]; - - NSValue *fromValue = nil; - NSValue *toValue = nil; - - if (![operation.period isKindOfClass:[PRTweenLerpPeriod class]] && ![operation.period conformsToProtocol:@protocol(PRTweenLerpPeriod)]) { - fromValue = [NSNumber numberWithFloat:operation.period.startValue]; - toValue = [NSNumber numberWithFloat:operation.period.endValue]; - } else { - PRTweenLerpPeriod *period = (PRTweenLerpPeriod *) operation.period; - fromValue = period.startLerp; - toValue = period.endLerp; - } - - [operation.boundObject setValue:fromValue forKeyPath:propertyFormatted]; - [UIView beginAnimations:nil context:NULL]; - [UIView setAnimationDuration:operation.period.duration]; - - if (operation.timingFunction == &PRTweenTimingFunctionUIViewEaseIn) { - [UIView setAnimationCurve:UIViewAnimationCurveEaseIn]; - } else if (operation.timingFunction == &PRTweenTimingFunctionUIViewEaseOut) { - [UIView setAnimationCurve:UIViewAnimationCurveEaseOut]; - } else if (operation.timingFunction == &PRTweenTimingFunctionUIViewEaseInOut) { - [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; - } else if (operation.timingFunction == &PRTweenTimingFunctionUIViewLinear) { - [UIView setAnimationCurve:UIViewAnimationCurveLinear]; - } - - [operation.boundObject setValue:toValue forKeyPath:propertyFormatted]; - [UIView commitAnimations]; - - goto complete; - } - } - } - - } - - complete: - [tweenOperations addObject:operation]; - return operation; -} - -#if NS_BLOCKS_AVAILABLE - -- (PRTweenOperation *)addTweenPeriod:(PRTweenPeriod *)period - updateBlock:(void (^)(PRTweenPeriod *period))updateBlock - completionBlock:(void (^)(BOOL finished))completeBlock { - return [self addTweenPeriod:period updateBlock:updateBlock completionBlock:completeBlock timingFunction:self.defaultTimingFunction]; -} - -- (PRTweenOperation *)addTweenPeriod:(PRTweenPeriod *)period - updateBlock:(void (^)(PRTweenPeriod *period))anUpdateBlock - completionBlock:(void (^)(BOOL finished))completeBlock - timingFunction:(PRTweenTimingFunction)timingFunction { - - PRTweenOperation *tweenOperation = [PRTweenOperation new]; - tweenOperation.period = period; - tweenOperation.timingFunction = timingFunction; - tweenOperation.updateBlock = anUpdateBlock; - tweenOperation.completeBlock = completeBlock; - tweenOperation.wasPreempted = NO; - return [self addTweenOperation:tweenOperation]; - -} - -#endif - -- (PRTweenOperation *)addTweenPeriod:(PRTweenPeriod *)period target:(NSObject *)target selector:(SEL)selector { - return [self addTweenPeriod:period target:target selector:selector timingFunction:self.defaultTimingFunction]; -} - -- (PRTweenOperation *)addTweenPeriod:(PRTweenPeriod *)period - target:(NSObject *)target - selector:(SEL)selector - timingFunction:(PRTweenTimingFunction)timingFunction { - - PRTweenOperation *tweenOperation = [PRTweenOperation new]; - tweenOperation.period = period; - tweenOperation.target = target; - tweenOperation.timingFunction = timingFunction; - tweenOperation.updateSelector = selector; - tweenOperation.wasPreempted = NO; - - return [self addTweenOperation:tweenOperation]; - -} - -- (void)removeTweenOperation:(PRTweenOperation *)tweenOperation { - if (tweenOperation != nil) { - if ([tweenOperations containsObject:tweenOperation]) { - tweenOperation.wasPreempted = YES; - [expiredTweenOperations addObject:tweenOperation]; - } - } -} - -- (void)removeAllTweenOperations { - for (PRTweenOperation *tweenOperation in tweenOperations) { - tweenOperation.wasPreempted = YES; - [expiredTweenOperations addObject:tweenOperation]; - } -} - -+ (SEL)setterFromProperty:(NSString *)property { - return NSSelectorFromString([NSString stringWithFormat:@"set%@:", [property stringByReplacingCharactersInRange:NSMakeRange(0, 1) withString:[[property substringToIndex:1] - capitalizedString]]]); -} - -- (void) update { - timeOffset += kPRTweenFramerate; - - for (PRTweenOperation *tweenOperation in tweenOperations) { - - PRTweenPeriod *period = tweenOperation.period; - - // if operation is delayed, pass over it for now - if (timeOffset <= period.startOffset + period.delay) { - continue; - } - - CGFloat (*timingFunction)(CGFloat, CGFloat, CGFloat, CGFloat) = tweenOperation.timingFunction; - if (timingFunction == NULL) { - timingFunction = self.defaultTimingFunction; - } - - if (timingFunction != NULL && tweenOperation.canUseBuiltAnimation == NO) { - if (timeOffset <= period.startOffset + period.delay + period.duration) { - if ([period isKindOfClass:[PRTweenLerpPeriod class]]) { - if ([period conformsToProtocol:@protocol(PRTweenLerpPeriod)]) { - PRTweenLerpPeriod *lerpPeriod = (PRTweenLerpPeriod *) period; - CGFloat progress = timingFunction(timeOffset - period.startOffset - period.delay, 0.0, 1.0, period.duration); - [lerpPeriod setProgress:progress]; - } else { - // @TODO: Throw exception - NSLog(@"Class doesn't conform to PRTweenLerp"); - } - } else { - // if tween operation is valid, calculate tweened value using timing function - period.tweenedValue = timingFunction(timeOffset - period.startOffset - period.delay, period.startValue, period.endValue - period.startValue, period.duration); - } - } else { - // move expired tween operations to list for cleanup - period.tweenedValue = period.endValue; - [expiredTweenOperations addObject:tweenOperation]; - } - - NSObject *target = tweenOperation.target; - SEL selector = tweenOperation.updateSelector; - - if (period != nil) { - if (target != nil && selector != NULL) { - [target performSelector:selector withObject:period afterDelay:0 inModes:[NSArray arrayWithObject:NSRunLoopCommonModes]]; - } - - // Check to see if blocks/GCD are supported - if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_4_0) { - // fire off update block - if (tweenOperation.updateBlock != NULL) { - tweenOperation.updateBlock(period); - } - } - } - } else if (tweenOperation.canUseBuiltAnimation == YES) { - if (timeOffset > period.startOffset + period.delay + period.duration) { - [expiredTweenOperations addObject:tweenOperation]; - } - } - } - - // clean up expired tween operations - for (__strong PRTweenOperation *tweenOperation in expiredTweenOperations) { - - if (tweenOperation.completeSelector) [tweenOperation.target performSelector:tweenOperation.completeSelector withObject:nil afterDelay:0 inModes:[NSArray arrayWithObject:NSRunLoopCommonModes]]; - - // Check to see if blocks/GCD are supported - if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_4_0) { - if (tweenOperation.completeBlock != NULL) { - tweenOperation.completeBlock(!tweenOperation.wasPreempted); - } - } - - if (tweenOperation.observers == PRTweenHasTweenedValueObserver) { - [tweenOperation removeObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedValue"]; - tweenOperation.observers = tweenOperation.observers & ~PRTweenHasTweenedValueObserver; - } - - if (tweenOperation.observers == PRTweenHasTweenedLerpObserver) { - [tweenOperation removeObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedLerp"]; - tweenOperation.observers = tweenOperation.observers & ~PRTweenHasTweenedLerpObserver; - } - - [tweenOperations removeObject:tweenOperation]; - tweenOperation = nil; - } - [expiredTweenOperations removeAllObjects]; -} - -- (void)dealloc { - tweenOperations = nil; - expiredTweenOperations = nil; - - [timer invalidate]; -} - -@end diff --git a/KACircleProgressView/External/PRTween/lib/PRTweenTimingFunctions.h b/KACircleProgressView/External/PRTween/lib/PRTweenTimingFunctions.h deleted file mode 100755 index 9b08b9b..0000000 --- a/KACircleProgressView/External/PRTween/lib/PRTweenTimingFunctions.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - - These timing functions are adapted from Robert Penner's excellent AS2 easing equations. - For more information, check out http://robertpenner.com/easing/ - - -- - - TERMS OF USE - EASING EQUATIONS - - Open source under the BSD License. - - Copyright © 2001 Robert Penner - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of the author nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -#import -#import - -CGFloat PRTweenTimingFunctionLinear (CGFloat, CGFloat, CGFloat, CGFloat); - -CGFloat PRTweenTimingFunctionBackOut (CGFloat, CGFloat, CGFloat, CGFloat); -CGFloat PRTweenTimingFunctionBackIn (CGFloat, CGFloat, CGFloat, CGFloat); -CGFloat PRTweenTimingFunctionBackInOut (CGFloat, CGFloat, CGFloat, CGFloat); - -CGFloat PRTweenTimingFunctionBounceOut (CGFloat, CGFloat, CGFloat, CGFloat); -CGFloat PRTweenTimingFunctionBounceIn (CGFloat, CGFloat, CGFloat, CGFloat); -CGFloat PRTweenTimingFunctionBounceInOut (CGFloat, CGFloat, CGFloat, CGFloat); - -CGFloat PRTweenTimingFunctionCircOut (CGFloat, CGFloat, CGFloat, CGFloat); -CGFloat PRTweenTimingFunctionCircIn (CGFloat, CGFloat, CGFloat, CGFloat); -CGFloat PRTweenTimingFunctionCircInOut (CGFloat, CGFloat, CGFloat, CGFloat); - -CGFloat PRTweenTimingFunctionCubicOut (CGFloat, CGFloat, CGFloat, CGFloat); -CGFloat PRTweenTimingFunctionCubicIn (CGFloat, CGFloat, CGFloat, CGFloat); -CGFloat PRTweenTimingFunctionCubicInOut (CGFloat, CGFloat, CGFloat, CGFloat); - -CGFloat PRTweenTimingFunctionElasticOut (CGFloat, CGFloat, CGFloat, CGFloat); -CGFloat PRTweenTimingFunctionElasticIn (CGFloat, CGFloat, CGFloat, CGFloat); -CGFloat PRTweenTimingFunctionElasticInOut (CGFloat, CGFloat, CGFloat, CGFloat); - -CGFloat PRTweenTimingFunctionExpoOut (CGFloat, CGFloat, CGFloat, CGFloat); -CGFloat PRTweenTimingFunctionExpoIn (CGFloat, CGFloat, CGFloat, CGFloat); -CGFloat PRTweenTimingFunctionExpoInOut (CGFloat, CGFloat, CGFloat, CGFloat); - -CGFloat PRTweenTimingFunctionQuadOut (CGFloat, CGFloat, CGFloat, CGFloat); -CGFloat PRTweenTimingFunctionQuadIn (CGFloat, CGFloat, CGFloat, CGFloat); -CGFloat PRTweenTimingFunctionQuadInOut (CGFloat, CGFloat, CGFloat, CGFloat); - -CGFloat PRTweenTimingFunctionQuartOut (CGFloat, CGFloat, CGFloat, CGFloat); -CGFloat PRTweenTimingFunctionQuartIn (CGFloat, CGFloat, CGFloat, CGFloat); -CGFloat PRTweenTimingFunctionQuartInOut (CGFloat, CGFloat, CGFloat, CGFloat); - -CGFloat PRTweenTimingFunctionQuintOut (CGFloat, CGFloat, CGFloat, CGFloat); -CGFloat PRTweenTimingFunctionQuintIn (CGFloat, CGFloat, CGFloat, CGFloat); -CGFloat PRTweenTimingFunctionQuintInOut (CGFloat, CGFloat, CGFloat, CGFloat); - -CGFloat PRTweenTimingFunctionSineOut (CGFloat, CGFloat, CGFloat, CGFloat); -CGFloat PRTweenTimingFunctionSineIn (CGFloat, CGFloat, CGFloat, CGFloat); -CGFloat PRTweenTimingFunctionSineInOut (CGFloat, CGFloat, CGFloat, CGFloat); - -CGFloat PRTweenTimingFunctionCALinear (CGFloat, CGFloat, CGFloat, CGFloat); -CGFloat PRTweenTimingFunctionCAEaseIn (CGFloat, CGFloat, CGFloat, CGFloat); -CGFloat PRTweenTimingFunctionCAEaseOut (CGFloat, CGFloat, CGFloat, CGFloat); -CGFloat PRTweenTimingFunctionCAEaseInOut (CGFloat, CGFloat, CGFloat, CGFloat); -CGFloat PRTweenTimingFunctionCADefault (CGFloat, CGFloat, CGFloat, CGFloat); - -CGFloat PRTweenTimingFunctionUIViewLinear (CGFloat, CGFloat, CGFloat, CGFloat); -CGFloat PRTweenTimingFunctionUIViewEaseIn (CGFloat, CGFloat, CGFloat, CGFloat); -CGFloat PRTweenTimingFunctionUIViewEaseOut (CGFloat, CGFloat, CGFloat, CGFloat); -CGFloat PRTweenTimingFunctionUIViewEaseInOut (CGFloat, CGFloat, CGFloat, CGFloat); - -CGFloat (*PRTweenTimingFunctionCACustom(CAMediaTimingFunction *timingFunction))(CGFloat, CGFloat, CGFloat, CGFloat); - - diff --git a/KACircleProgressView/External/PRTween/lib/PRTweenTimingFunctions.m b/KACircleProgressView/External/PRTween/lib/PRTweenTimingFunctions.m deleted file mode 100755 index 5161d8a..0000000 --- a/KACircleProgressView/External/PRTween/lib/PRTweenTimingFunctions.m +++ /dev/null @@ -1,230 +0,0 @@ -/* - - These timing functions are adapted from Robert Penner's excellent AS2 easing equations. - For more information, check out http://robertpenner.com/easing/ - - -- - - TERMS OF USE - EASING EQUATIONS - - Open source under the BSD License. - - Copyright © 2001 Robert Penner - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of the author nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -#import "PRTweenTimingFunctions.h" - -CGFloat PRTweenTimingFunctionLinear (CGFloat time, CGFloat begin, CGFloat change, CGFloat duration) { - return change * time / duration + begin; -} - -CGFloat PRTweenTimingFunctionBackOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { - CGFloat s = 1.70158; - t=t/d-1; - return c*(t*t*((s+1)*t + s) + 1) + b; -} - -CGFloat PRTweenTimingFunctionBackIn (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { - CGFloat s = 1.70158; - t/=d; - return c*t*t*((s+1)*t - s) + b; -} - -CGFloat PRTweenTimingFunctionBackInOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { - CGFloat s = 1.70158; - if ((t/=d/2) < 1) { - s*=(1.525); - return c/2*(t*t*((s+1)*t - s)) + b; - } - t-=2; - s*=(1.525); - return c/2*(t*t*((s+1)*t + s) + 2) + b; -} - -CGFloat PRTweenTimingFunctionBounceOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { - if ((t/=d) < (1/2.75)) { - return c*(7.5625*t*t) + b; - } else if (t < (2/2.75)) { - t-=(1.5/2.75); - return c*(7.5625*t*t + .75) + b; - } else if (t < (2.5/2.75)) { - t-=(2.25/2.75); - return c*(7.5625*t*t + .9375) + b; - } else { - t-=(2.625/2.75); - return c*(7.5625*t*t + .984375) + b; - } -} - -CGFloat PRTweenTimingFunctionBounceIn (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { - return c - PRTweenTimingFunctionBounceOut(d-t, 0, c, d) + b; -} - -CGFloat PRTweenTimingFunctionBounceInOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { - if (t < d/2) return PRTweenTimingFunctionBounceIn(t*2, 0, c, d) * .5 + b; - else return PRTweenTimingFunctionBounceOut(t*2-d, 0, c, d) * .5 + c*.5 + b; -} - -CGFloat PRTweenTimingFunctionCircOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { - t=t/d-1; - return c * sqrt(1 - t*t) + b; -} - -CGFloat PRTweenTimingFunctionCircIn (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { - t/=d; - return -c * (sqrt(1 - t*t) - 1) + b; -} - -CGFloat PRTweenTimingFunctionCircInOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { - if ((t/=d/2) < 1) return -c/2 * (sqrt(1 - t*t) - 1) + b; - t-=2; - return c/2 * (sqrt(1 - t*t) + 1) + b; -} - -CGFloat PRTweenTimingFunctionCubicOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { - t=t/d-1; - return c*(t*t*t + 1) + b; -} - -CGFloat PRTweenTimingFunctionCubicIn (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { - t/=d; - return c*t*t*t + b; -} - -CGFloat PRTweenTimingFunctionCubicInOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { - if ((t/=d/2) < 1) return c/2*t*t*t + b; - t-=2; - return c/2*(t*t*t + 2) + b; -} - -CGFloat PRTweenTimingFunctionElasticOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { - CGFloat p = d*.3; - CGFloat s, a = .0; - if (t==0) return b; if ((t/=d)==1) return b+c; - if (!a || a < ABS(c)) { a=c; s=p/4; } - else s = p/(2*M_PI) * asin (c/a); - return (a*pow(2,-10*t) * sin( (t*d-s)*(2*M_PI)/p ) + c + b); -} - -CGFloat PRTweenTimingFunctionElasticIn (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { - CGFloat p = d*.3; - CGFloat s, a = .0; - if (t==0) return b; if ((t/=d)==1) return b+c; - if (!a || a < ABS(c)) { a=c; s=p/4; } - else s = p/(2*M_PI) * asin (c/a); - t-=1; - return -(a*pow(2,10*t) * sin( (t*d-s)*(2*M_PI)/p )) + b; -} - -CGFloat PRTweenTimingFunctionElasticInOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { - CGFloat p = d*(.3*1.5); - CGFloat s, a = .0; - if (t==0) return b; if ((t/=d/2)==2) return b+c; - if (!a || a < ABS(c)) { a=c; s=p/4; } - else s = p/(2*M_PI) * asin (c/a); - if (t < 1) { - t-=1; - return -.5*(a*pow(2,10*t) * sin( (t*d-s)*(2*M_PI)/p )) + b; - } - t-=1; - return a*pow(2,-10*t) * sin( (t*d-s)*(2*M_PI)/p )*.5 + c + b; -} - -CGFloat PRTweenTimingFunctionExpoOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { - return (t==d) ? b+c : c * (-pow(2, -10 * t/d) + 1) + b; -} - -CGFloat PRTweenTimingFunctionExpoIn (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { - return (t==0) ? b : c * pow(2, 10 * (t/d - 1)) + b; -} - -CGFloat PRTweenTimingFunctionExpoInOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { - if (t==0) return b; - if (t==d) return b+c; - if ((t/=d/2) < 1) return c/2 * pow(2, 10 * (t - 1)) + b; - return c/2 * (-pow(2, -10 * --t) + 2) + b; -} - -CGFloat PRTweenTimingFunctionQuadOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { - t/=d; - return -c *t*(t-2) + b; -} - -CGFloat PRTweenTimingFunctionQuadIn (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { - t/=d; - return c*t*t + b; -} - -CGFloat PRTweenTimingFunctionQuadInOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { - if ((t/=d/2) < 1) return c/2*t*t + b; - t--; - return -c/2 * (t*(t-2) - 1) + b; -} - -CGFloat PRTweenTimingFunctionQuartOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { - t=t/d-1; - return -c * (t*t*t*t - 1) + b; -} - -CGFloat PRTweenTimingFunctionQuartIn (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { - t/=d; - return c*t*t*t*t + b; -} - -CGFloat PRTweenTimingFunctionQuartInOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { - if ((t/=d/2) < 1) return c/2*t*t*t*t + b; - t-=2; - return -c/2 * (t*t*t*t - 2) + b; -} - -CGFloat PRTweenTimingFunctionQuintOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { - t=t/d-1; - return c*(t*t*t*t*t + 1) + b; -} - -CGFloat PRTweenTimingFunctionQuintIn (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { - t/=d; - return c*t*t*t*t*t + b; -} - -CGFloat PRTweenTimingFunctionQuintInOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { - if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b; - t-=2; - return c/2*(t*t*t*t*t + 2) + b; -} - -CGFloat PRTweenTimingFunctionSineOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { - return c * sin(t/d * (M_PI/2)) + b; -} - -CGFloat PRTweenTimingFunctionSineIn (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { - return -c * cos(t/d * (M_PI/2)) + c + b; -} - -CGFloat PRTweenTimingFunctionSineInOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { - return -c/2 * (cos(M_PI*t/d) - 1) + b; -} - -CGFloat PRTweenTimingFunctionCALinear (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { return 0; } -CGFloat PRTweenTimingFunctionCAEaseIn (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { return 0; } -CGFloat PRTweenTimingFunctionCAEaseOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { return 0; } -CGFloat PRTweenTimingFunctionCAEaseInOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { return 0; } -CGFloat PRTweenTimingFunctionCADefault (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { return 0; } - -CGFloat PRTweenTimingFunctionUIViewLinear (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { return 0; } -CGFloat PRTweenTimingFunctionUIViewEaseIn (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { return 0; } -CGFloat PRTweenTimingFunctionUIViewEaseOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { return 0; } -CGFloat PRTweenTimingFunctionUIViewEaseInOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { return 0; } - -CGFloat (*PRTweenTimingFunctionCACustom(CAMediaTimingFunction *timingFunction))(CGFloat, CGFloat, CGFloat, CGFloat) { - return &PRTweenTimingFunctionLinear; -} From ead9f16b73725afea481fe3b08f0c2a72834e615 Mon Sep 17 00:00:00 2001 From: John Pope Date: Wed, 4 Dec 2013 11:51:42 +1100 Subject: [PATCH 6/6] animation tweaking --- KACircleProgressView/KAViewController.m | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/KACircleProgressView/KAViewController.m b/KACircleProgressView/KAViewController.m index 246214b..30bbf11 100755 --- a/KACircleProgressView/KAViewController.m +++ b/KACircleProgressView/KAViewController.m @@ -28,7 +28,7 @@ - (void)viewDidLoad [circlePV.button addTarget:self action:@selector(refresh) forControlEvents:UIControlEventTouchUpInside]; [circlePV.button setTitle:@"Tap to refresh" forState:UIControlStateNormal]; circlePV.button.layer.borderColor=[UIColor darkGrayColor].CGColor; - circlePV.frame = CGRectMake(100, 200, 200, 200); + circlePV.frame = CGRectMake(40, 220, 200, 200); slider0 = [[UISlider alloc]initWithFrame:CGRectMake(10, 20, 200, 30)]; [slider0 setMinimumValue:0]; @@ -101,7 +101,7 @@ -(void)refresh{ PRTweenOperation *operation = [PRTweenOperation new]; operation.period = period; operation.target = self; - operation.timingFunction = &PRTweenTimingFunctionLinear; + operation.timingFunction = &PRTweenTimingFunctionCircOut; operation.updateSelector = @selector(update:); [[PRTween sharedInstance] addTweenOperation:operation]; @@ -110,24 +110,21 @@ -(void)refresh{ -(void)animate{ PRTweenPeriod *period = [PRTweenPeriod periodWithStartValue:currentValue endValue:slider0.value duration:duration]; - PRTweenOperation *operation = [PRTweenOperation new]; operation.period = period; operation.target = self; - operation.timingFunction = &PRTweenTimingFunctionLinear; + operation.timingFunction = &PRTweenTimingFunctionCircOut; operation.updateSelector = @selector(update:); - [[PRTween sharedInstance] addTweenOperation:operation]; } - (void)update:(PRTweenPeriod*)period { - // NSLog(@"update %.2f",period.tweenedValue); + CGFloat f =period.tweenedValue; [circlePV setProgress:f]; [circlePV setNeedsDisplay]; - //[circlePV setColorOfProgressBar:[UIColor colorWithRed:1 green:1-f blue:1-f alpha:1]]; - + }