From 967d2423577af44571fcba3deafaaecf9ff0a034 Mon Sep 17 00:00:00 2001 From: Gilles Guillemin Date: Tue, 16 Oct 2012 19:23:17 +0100 Subject: [PATCH 01/21] PRTweenTimingFunctionQuintIn and PRTweenTimingFunctionQuintOut were inverted --- lib/PRTweenTimingFunctions.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/PRTweenTimingFunctions.m b/lib/PRTweenTimingFunctions.m index da42860..c789a0c 100755 --- a/lib/PRTweenTimingFunctions.m +++ b/lib/PRTweenTimingFunctions.m @@ -160,11 +160,11 @@ CGFloat PRTweenTimingFunctionQuartInOut (CGFloat t, CGFloat b, CGFloat c, CGFloa } CGFloat PRTweenTimingFunctionQuintOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { - return c*(t/=d)*t*t*t*t + b; + return c*((t=t/d-1)*t*t*t*t + 1) + b; } CGFloat PRTweenTimingFunctionQuintIn (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { - return c*((t=t/d-1)*t*t*t*t + 1) + b; + return c*(t/=d)*t*t*t*t + b; } CGFloat PRTweenTimingFunctionQuintInOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { @@ -197,4 +197,4 @@ CGFloat PRTweenTimingFunctionSineInOut (CGFloat t, CGFloat b, CGFloat c, CGFloat CGFloat (*PRTweenTimingFunctionCACustom(CAMediaTimingFunction *timingFunction))(CGFloat, CGFloat, CGFloat, CGFloat) { return &PRTweenTimingFunctionLinear; -} \ No newline at end of file +} From da9b0c80a76427496c11e811377e4997268116ba Mon Sep 17 00:00:00 2001 From: Gilles Guillemin Date: Tue, 16 Oct 2012 19:26:58 +0100 Subject: [PATCH 02/21] Added a couple of additional shorthand methods to include delay with blocks --- lib/PRTween.h | 2 ++ lib/PRTween.m | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/lib/PRTween.h b/lib/PRTween.h index d781cbd..31c3127 100755 --- a/lib/PRTween.h +++ b/lib/PRTween.h @@ -27,6 +27,7 @@ typedef void (^PRTweenCompleteBlock)(); @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 @@ -119,6 +120,7 @@ typedef void (^PRTweenCompleteBlock)(); + (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 diff --git a/lib/PRTween.m b/lib/PRTween.m index 3c41f3b..e1993b6 100755 --- a/lib/PRTween.m +++ b/lib/PRTween.m @@ -22,6 +22,18 @@ + (id)periodWithStartValue:(CGFloat)aStartValue endValue:(CGFloat)anEndValue dur 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 @@ -166,6 +178,12 @@ + (PRTweenOperation *)lerp:(id)object property:(NSString *)property from:(CGPoin + (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.delay = delay; + return [PRTween lerp:object property:property period:period timingFunction:timingFunction updateBlock:updateBlock completeBlock:completeBlock]; +} #endif @end From e8e6686dd842e5b84df1d916dd5f1b0fbf415128 Mon Sep 17 00:00:00 2001 From: Gilles Guillemin Date: Tue, 16 Oct 2012 19:30:17 +0100 Subject: [PATCH 03/21] Fix for the hack to remove observers (still a bit hackish though but at least now it doesn't mess up with the All Exceptions breakpoint) --- lib/PRTween.h | 12 +++++++++++- lib/PRTween.m | 39 ++++++++++++++++++++++++++------------- 2 files changed, 37 insertions(+), 14 deletions(-) diff --git a/lib/PRTween.h b/lib/PRTween.h index 31c3127..c2ab583 100755 --- a/lib/PRTween.h +++ b/lib/PRTween.h @@ -10,6 +10,12 @@ typedef void (^PRTweenUpdateBlock)(PRTweenPeriod *period); typedef void (^PRTweenCompleteBlock)(); #endif +enum { + PRTweenHasTweenedValueObserver = 1 << 0, + PRTweenHasTweenedLerpObserver = 1 << 1, +}; +typedef NSUInteger PRTweenHasTweenedObserverOptions; + @interface PRTweenPeriod : NSObject { CGFloat duration; CGFloat delay; @@ -85,10 +91,12 @@ typedef void (^PRTweenCompleteBlock)(); SEL boundSetter; BOOL override; + + PRTweenHasTweenedObserverOptions observers; #if NS_BLOCKS_AVAILABLE PRTweenUpdateBlock updateBlock; - PRTweenCompleteBlock completeBlock; + PRTweenCompleteBlock completeBlock; #endif @private @@ -112,6 +120,8 @@ typedef void (^PRTweenCompleteBlock)(); @property (nonatomic) SEL boundSetter; @property (nonatomic) BOOL override; +@property (nonatomic) PRTweenHasTweenedObserverOptions observers; + @end @interface PRTweenCGPointLerp : NSObject diff --git a/lib/PRTween.m b/lib/PRTween.m index e1993b6..3ed6088 100755 --- a/lib/PRTween.m +++ b/lib/PRTween.m @@ -150,6 +150,7 @@ @implementation PRTweenOperation @synthesize boundSetter; @synthesize canUseBuiltAnimation; @synthesize override; +@synthesize observers; #if NS_BLOCKS_AVAILABLE @synthesize updateBlock; @@ -269,7 +270,8 @@ + (PRTweenOperation *)tween:(id)object property:(NSString*)property from:(CGFloa operation.boundObject = object; operation.boundGetter = NSSelectorFromString([NSString stringWithFormat:@"%@", property]); operation.boundSetter = [PRTween setterFromProperty:property]; - [operation addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedValue" options:NSKeyValueObservingOptionNew context:NULL]; +// [operation addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedValue" options:NSKeyValueObservingOptionNew context:NULL]; + [self addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedValue" observerOptions:PRTweenHasTweenedValueObserver operation:operation]; [[PRTween sharedInstance] performSelector:@selector(addTweenOperation:) withObject:operation afterDelay:0]; return operation; @@ -285,7 +287,9 @@ + (PRTweenOperation *)tween:(CGFloat *)ref from:(CGFloat)from to:(CGFloat)to dur operation.target = target; operation.completeSelector = selector; operation.boundRef = ref; - [operation addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedValue" options:NSKeyValueObservingOptionNew context:NULL]; + // operation.observers +// [operation addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedValue" options:NSKeyValueObservingOptionNew context:NULL]; + [self addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedValue" observerOptions:PRTweenHasTweenedValueObserver operation:operation]; [[PRTween sharedInstance] performSelector:@selector(addTweenOperation:) withObject:operation afterDelay:0]; return operation; @@ -311,7 +315,8 @@ + (PRTweenOperation *)lerp:(id)object property:(NSString *)property period:(PRTw operation.boundObject = object; operation.boundGetter = NSSelectorFromString([NSString stringWithFormat:@"%@", property]); operation.boundSetter = [PRTween setterFromProperty:property]; - [operation addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedLerp" options:NSKeyValueObservingOptionNew context:NULL]; +// [operation addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedLerp" options:NSKeyValueObservingOptionNew context:NULL]; + [self addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedLerp" observerOptions:PRTweenHasTweenedLerpObserver operation:operation]; [[PRTween sharedInstance] performSelector:@selector(addTweenOperation:) withObject:operation afterDelay:0]; return operation; @@ -330,7 +335,8 @@ + (PRTweenOperation *)tween:(id)object property:(NSString*)property from:(CGFloa operation.boundObject = object; operation.boundGetter = NSSelectorFromString([NSString stringWithFormat:@"%@", property]); operation.boundSetter = [PRTween setterFromProperty:property]; - [operation addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedValue" options:NSKeyValueObservingOptionNew context:NULL]; +// [operation addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedValue" options:NSKeyValueObservingOptionNew context:NULL]; + [self addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedValue" observerOptions:PRTweenHasTweenedValueObserver operation:operation]; [[PRTween sharedInstance] performSelector:@selector(addTweenOperation:) withObject:operation afterDelay:0]; return operation; @@ -346,7 +352,8 @@ + (PRTweenOperation *)tween:(CGFloat *)ref from:(CGFloat)from to:(CGFloat)to dur operation.updateBlock = updateBlock; operation.completeBlock = completeBlock; operation.boundRef = ref; - [operation addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedValue" options:NSKeyValueObservingOptionNew context:NULL]; +// [operation addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedValue" options:NSKeyValueObservingOptionNew context:NULL]; + [self addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedValue" observerOptions:PRTweenHasTweenedValueObserver operation:operation]; [[PRTween sharedInstance] performSelector:@selector(addTweenOperation:) withObject:operation afterDelay:0]; return operation; @@ -364,7 +371,8 @@ + (PRTweenOperation *)lerp:(id)object property:(NSString *)property period:(PRTw operation.boundObject = object; operation.boundGetter = NSSelectorFromString([NSString stringWithFormat:@"%@", property]); operation.boundSetter = [PRTween setterFromProperty:property]; - [operation addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedLerp" options:NSKeyValueObservingOptionNew context:NULL]; +// [operation addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedLerp" options:NSKeyValueObservingOptionNew context:NULL]; + [self addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedLerp" observerOptions:PRTweenHasTweenedLerpObserver operation:operation]; [[PRTween sharedInstance] performSelector:@selector(addTweenOperation:) withObject:operation afterDelay:0]; return operation; @@ -372,6 +380,11 @@ + (PRTweenOperation *)lerp:(id)object property:(NSString *)property period:(PRTw } #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; @@ -694,15 +707,15 @@ - (void)update { } } - // @HACK: Come up with a better pattern for removing observers. - @try { + if (tweenOperation.observers == PRTweenHasTweenedValueObserver) { [tweenOperation removeObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedValue"]; - } @catch (id exception) { - } - @try { + tweenOperation.observers = tweenOperation.observers & ~PRTweenHasTweenedValueObserver; + } + + if (tweenOperation.observers == PRTweenHasTweenedLerpObserver) { [tweenOperation removeObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedLerp"]; - } @catch (id exception) { - } + tweenOperation.observers = tweenOperation.observers & ~PRTweenHasTweenedLerpObserver; + } [tweenOperations removeObject:tweenOperation]; tweenOperation = nil; From 34b171c135d83f7221ba948ee1406a04eb04b87a Mon Sep 17 00:00:00 2001 From: Gilles Guillemin Date: Wed, 17 Oct 2012 05:32:52 +0100 Subject: [PATCH 04/21] Included some additional methods to include delay more systematically. Formatted code for better readability (at least for me) --- lib/PRTween.h | 273 ++++++++++++++++++++++++---- lib/PRTween.m | 488 ++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 668 insertions(+), 93 deletions(-) diff --git a/lib/PRTween.h b/lib/PRTween.h index c2ab583..4443920 100755 --- a/lib/PRTween.h +++ b/lib/PRTween.h @@ -32,8 +32,14 @@ typedef NSUInteger PRTweenHasTweenedObserverOptions; @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; ++ (id)periodWithStartValue:(CGFloat)aStartValue + endValue:(CGFloat)anEndValue + duration:(CGFloat)duration; + ++ (id)periodWithStartValue:(CGFloat)aStartValue + endValue:(CGFloat)anEndValue + duration:(CGFloat)duration + delay:(CGFloat)delay; @end @@ -54,26 +60,43 @@ typedef NSUInteger PRTweenHasTweenedObserverOptions; @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; ++ (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; ++ (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; ++ (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; + ++ (id)periodWithStartCGSize:(CGSize)aStartSize + endCGSize:(CGSize)anEndSize + duration:(CGFloat)duration + delay:(CGFloat)delay; - (CGSize)startCGSize; - (CGSize)tweenedCGSize; - (CGSize)endCGSize; @@ -125,30 +148,142 @@ typedef NSUInteger PRTweenHasTweenedObserverOptions; @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; ++ (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; ++ (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; ++ (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 + 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; ++ (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 + 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 @@ -168,30 +303,96 @@ typedef NSUInteger PRTweenHasTweenedObserverOptions; + (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:(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:(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 *)tween:(id)object property:(NSString*)property from:(CGFloat)from to:(CGFloat)to duration:(CGFloat)duration; +- (PRTweenOperation *)addTweenOperation:(PRTweenOperation*)operation; -+ (PRTweenOperation *)tween:(CGFloat*)ref from:(CGFloat)from to:(CGFloat)to duration:(CGFloat)duration; +- (PRTweenOperation *)addTweenPeriod:(PRTweenPeriod *)period + target:(NSObject *)target + selector:(SEL)selector; -+ (PRTweenOperation *)lerp:(id)object property:(NSString*)property period:(PRTweenLerpPeriod *)period timingFunction:(PRTweenTimingFunction)timingFunction target:(NSObject *)target completeSelector:(SEL)selector; +- (PRTweenOperation *)addTweenPeriod:(PRTweenPeriod *)period + target:(NSObject *)target + selector:(SEL)selector + timingFunction:(PRTweenTimingFunction)timingFunction; -- (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; #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:(CGFloat*)ref from:(CGFloat)from to:(CGFloat)to duration:(CGFloat)duration 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; ++ (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 *)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/lib/PRTween.m b/lib/PRTween.m index 3ed6088..70b885a 100755 --- a/lib/PRTween.m +++ b/lib/PRTween.m @@ -11,7 +11,10 @@ @implementation PRTweenPeriod @synthesize delay; @synthesize startOffset; -+ (id)periodWithStartValue:(CGFloat)aStartValue endValue:(CGFloat)anEndValue duration:(CGFloat)duration { ++ (id)periodWithStartValue:(CGFloat)aStartValue + endValue:(CGFloat)anEndValue + duration:(CGFloat)duration { + PRTweenPeriod *period = [PRTweenPeriod new]; period.startValue = period.tweenedValue = aStartValue; @@ -22,7 +25,11 @@ + (id)periodWithStartValue:(CGFloat)aStartValue endValue:(CGFloat)anEndValue dur return period; } -+ (id)periodWithStartValue:(CGFloat)aStartValue endValue:(CGFloat)anEndValue duration:(CGFloat)duration delay:(CGFloat)delay { ++ (id)periodWithStartValue:(CGFloat)aStartValue + endValue:(CGFloat)anEndValue + duration:(CGFloat)duration + delay:(CGFloat)delay { + PRTweenPeriod *period = [PRTweenPeriod new]; period.startValue = period.tweenedValue = aStartValue; @@ -41,7 +48,10 @@ @implementation PRTweenLerpPeriod @synthesize endLerp; @synthesize tweenedLerp; -+ (id)periodWithStartValue:(NSValue*)aStartValue endValue:(NSValue*)anEndValue duration:(CGFloat)duration { ++ (id)periodWithStartValue:(NSValue*)aStartValue + endValue:(NSValue*)anEndValue + duration:(CGFloat)duration { + PRTweenLerpPeriod *period = [[self class] new]; period.startLerp = aStartValue; period.tweenedLerp = aStartValue; @@ -52,11 +62,30 @@ + (id)periodWithStartValue:(NSValue*)aStartValue endValue:(NSValue*)anEndValue d 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 { ++ (id)periodWithStartCGPoint:(CGPoint)aStartPoint + endCGPoint:(CGPoint)anEndPoint + duration:(CGFloat)duration { + return [PRTweenCGPointLerpPeriod periodWithStartValue:[NSValue valueWithCGPoint:aStartPoint] endValue:[NSValue valueWithCGPoint:anEndPoint] duration:duration]; } @@ -83,7 +112,10 @@ - (void)setProgress:(CGFloat)progress { @implementation PRTweenCGRectLerpPeriod -+ (id)periodWithStartCGRect:(CGRect)aStartRect endCGRect:(CGRect)anEndRect duration:(CGFloat)duration { ++ (id)periodWithStartCGRect:(CGRect)aStartRect + endCGRect:(CGRect)anEndRect + duration:(CGFloat)duration { + return [PRTweenCGRectLerpPeriod periodWithStartValue:[NSValue valueWithCGRect:aStartRect] endValue:[NSValue valueWithCGRect:anEndRect] duration:duration]; } @@ -110,10 +142,21 @@ - (void)setProgress:(CGFloat)progress { @implementation PRTweenCGSizeLerpPeriod -+ (id)periodWithStartCGSize:(CGSize)aStartSize endCGSize:(CGSize)anEndSize duration:(CGFloat)duration { ++ (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]; } @@ -161,29 +204,106 @@ @implementation PRTweenOperation @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 + 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 { ++ (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]; + + 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]; ++ (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 + 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]; ++ (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.delay = delay; - return [PRTween lerp:object property:property period:period timingFunction:timingFunction updateBlock:updateBlock completeBlock:completeBlock]; + return [PRTween lerp:object + property:property + period:period + timingFunction:timingFunction + updateBlock:updateBlock + completeBlock:completeBlock]; } #endif @@ -191,23 +311,103 @@ + (PRTweenOperation *)lerp:(id)object property:(NSString *)property from:(CGPoin @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 + 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]; ++ (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]; + 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]; ++ (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 [PRTweenCGRectLerp lerp:object property:property from:from to: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 + timingFunction:(PRTweenTimingFunction)timingFunction + updateBlock:(PRTweenUpdateBlock)updateBlock + completeBlock:(PRTweenCompleteBlock)completeBlock { + + return [PRTweenCGRectLerp lerp:object + property:property + from:from + to: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 { + + return [PRTweenCGRectLerp lerp:object + property:property + from:from + to:to + duration:duration + delay:delay + timingFunction:timingFunction + updateBlock:updateBlock + completeBlock:completeBlock]; } #endif @@ -215,24 +415,107 @@ + (PRTweenOperation *)lerp:(id)object property:(NSString *)property from:(CGRect @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 + 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]; ++ (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]; + 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]; ++ (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]; ++ (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]; +} + ++ (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 { + + return [PRTween lerp:object + property:property + period:[PRTweenCGSizeLerpPeriod + periodWithStartCGSize:from + endCGSize:to + duration:duration + delay:delay] + timingFunction:timingFunction + updateBlock:updateBlock + completeBlock:completeBlock]; } + #endif @end @@ -259,9 +542,18 @@ + (PRTween *)sharedInstance { 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 { ++ (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]; + PRTweenPeriod *period = [PRTweenPeriod periodWithStartValue:from + endValue:to + duration:duration]; PRTweenOperation *operation = [PRTweenOperation new]; operation.period = period; operation.timingFunction = timingFunction; @@ -270,7 +562,6 @@ + (PRTweenOperation *)tween:(id)object property:(NSString*)property from:(CGFloa operation.boundObject = object; operation.boundGetter = NSSelectorFromString([NSString stringWithFormat:@"%@", property]); operation.boundSetter = [PRTween setterFromProperty:property]; -// [operation addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedValue" options:NSKeyValueObservingOptionNew context:NULL]; [self addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedValue" observerOptions:PRTweenHasTweenedValueObserver operation:operation]; [[PRTween sharedInstance] performSelector:@selector(addTweenOperation:) withObject:operation afterDelay:0]; @@ -278,17 +569,22 @@ + (PRTweenOperation *)tween:(id)object property:(NSString*)property from:(CGFloa } -+ (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 + timingFunction:(PRTweenTimingFunction)timingFunction + target:(NSObject*)target + completeSelector:(SEL)selector { - PRTweenPeriod *period = [PRTweenPeriod periodWithStartValue:from endValue:to duration:duration]; + 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.observers -// [operation addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedValue" options:NSKeyValueObservingOptionNew context:NULL]; [self addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedValue" observerOptions:PRTweenHasTweenedValueObserver operation:operation]; [[PRTween sharedInstance] performSelector:@selector(addTweenOperation:) withObject:operation afterDelay:0]; @@ -296,15 +592,42 @@ + (PRTweenOperation *)tween:(CGFloat *)ref from:(CGFloat)from to:(CGFloat)to dur } -+ (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:(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 *)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 { ++ (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]; @@ -315,7 +638,6 @@ + (PRTweenOperation *)lerp:(id)object property:(NSString *)property period:(PRTw operation.boundObject = object; operation.boundGetter = NSSelectorFromString([NSString stringWithFormat:@"%@", property]); operation.boundSetter = [PRTween setterFromProperty:property]; -// [operation addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedLerp" options:NSKeyValueObservingOptionNew context:NULL]; [self addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedLerp" observerOptions:PRTweenHasTweenedLerpObserver operation:operation]; [[PRTween sharedInstance] performSelector:@selector(addTweenOperation:) withObject:operation afterDelay:0]; @@ -324,9 +646,47 @@ + (PRTweenOperation *)lerp:(id)object property:(NSString *)property period:(PRTw } #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 + 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]; + [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]; + PRTweenPeriod *period = [PRTweenPeriod periodWithStartValue:from + endValue:to + duration:duration + delay:delay]; PRTweenOperation *operation = [PRTweenOperation new]; operation.period = period; operation.timingFunction = timingFunction; @@ -335,7 +695,6 @@ + (PRTweenOperation *)tween:(id)object property:(NSString*)property from:(CGFloa operation.boundObject = object; operation.boundGetter = NSSelectorFromString([NSString stringWithFormat:@"%@", property]); operation.boundSetter = [PRTween setterFromProperty:property]; -// [operation addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedValue" options:NSKeyValueObservingOptionNew context:NULL]; [self addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedValue" observerOptions:PRTweenHasTweenedValueObserver operation:operation]; [[PRTween sharedInstance] performSelector:@selector(addTweenOperation:) withObject:operation afterDelay:0]; @@ -343,16 +702,23 @@ + (PRTweenOperation *)tween:(id)object property:(NSString*)property from:(CGFloa } -+ (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 + timingFunction:(PRTweenTimingFunction)timingFunction + updateBlock:(PRTweenUpdateBlock)updateBlock + completeBlock:(PRTweenCompleteBlock)completeBlock { - PRTweenPeriod *period = [PRTweenPeriod periodWithStartValue:from endValue:to duration:duration]; + 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 addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedValue" options:NSKeyValueObservingOptionNew context:NULL]; [self addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedValue" observerOptions:PRTweenHasTweenedValueObserver operation:operation]; [[PRTween sharedInstance] performSelector:@selector(addTweenOperation:) withObject:operation afterDelay:0]; @@ -360,7 +726,12 @@ + (PRTweenOperation *)tween:(CGFloat *)ref from:(CGFloat)from to:(CGFloat)to dur } -+ (PRTweenOperation *)lerp:(id)object property:(NSString *)property period:(PRTweenLerpPeriod *)period 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 { //PRTweenPeriod *period = [PRTweenLerpPeriod periodWithStartValue:from endValue:to duration:duration]; PRTweenOperation *operation = [PRTweenOperation new]; @@ -371,7 +742,6 @@ + (PRTweenOperation *)lerp:(id)object property:(NSString *)property period:(PRTw operation.boundObject = object; operation.boundGetter = NSSelectorFromString([NSString stringWithFormat:@"%@", property]); operation.boundSetter = [PRTween setterFromProperty:property]; -// [operation addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedLerp" options:NSKeyValueObservingOptionNew context:NULL]; [self addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedLerp" observerOptions:PRTweenHasTweenedLerpObserver operation:operation]; [[PRTween sharedInstance] performSelector:@selector(addTweenOperation:) withObject:operation afterDelay:0]; @@ -380,7 +750,11 @@ + (PRTweenOperation *)lerp:(id)object property:(NSString *)property period:(PRTw } #endif -+ (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath observerOptions:(PRTweenHasTweenedObserverOptions)observerOptions operation:(PRTweenOperation *)operation { ++ (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; } From 682f78b2b79adae997cfcbc455b2ae225d2f37d4 Mon Sep 17 00:00:00 2001 From: Gilles Guillemin Date: Wed, 17 Oct 2012 06:11:59 +0100 Subject: [PATCH 05/21] Added yet another method including a delay property. --- lib/PRTween.h | 9 +++++++++ lib/PRTween.m | 29 ++++++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/lib/PRTween.h b/lib/PRTween.h index 4443920..10200e2 100755 --- a/lib/PRTween.h +++ b/lib/PRTween.h @@ -320,6 +320,15 @@ typedef NSUInteger PRTweenHasTweenedObserverOptions; 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 diff --git a/lib/PRTween.m b/lib/PRTween.m index 70b885a..0b06c52 100755 --- a/lib/PRTween.m +++ b/lib/PRTween.m @@ -571,7 +571,8 @@ + (PRTweenOperation *)tween:(id)object + (PRTweenOperation *)tween:(CGFloat *)ref from:(CGFloat)from - to:(CGFloat)to duration:(CGFloat)duration + to:(CGFloat)to + duration:(CGFloat)duration timingFunction:(PRTweenTimingFunction)timingFunction target:(NSObject*)target completeSelector:(SEL)selector { @@ -592,6 +593,32 @@ + (PRTweenOperation *)tween:(CGFloat *)ref } ++ (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; + [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 From 7f5665b3189fd4001e24d5947c2db2ce4fa72920 Mon Sep 17 00:00:00 2001 From: Gilles Guillemin Date: Wed, 17 Oct 2012 11:26:30 +0100 Subject: [PATCH 06/21] Another method with delay + added a removeAllTweenOperations --- lib/PRTween.h | 10 ++++++++++ lib/PRTween.m | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/lib/PRTween.h b/lib/PRTween.h index 10200e2..3adf0c4 100755 --- a/lib/PRTween.h +++ b/lib/PRTween.h @@ -359,6 +359,7 @@ typedef NSUInteger PRTweenHasTweenedObserverOptions; timingFunction:(PRTweenTimingFunction)timingFunction; - (void)removeTweenOperation:(PRTweenOperation*)tweenOperation; +- (void)removeAllTweenOperations; #if NS_BLOCKS_AVAILABLE + (PRTweenOperation *)tween:(id)object @@ -387,6 +388,15 @@ typedef NSUInteger PRTweenHasTweenedObserverOptions; 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 diff --git a/lib/PRTween.m b/lib/PRTween.m index 0b06c52..114a400 100755 --- a/lib/PRTween.m +++ b/lib/PRTween.m @@ -753,6 +753,32 @@ + (PRTweenOperation *)tween:(CGFloat *)ref } ++ (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; + [self addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedValue" observerOptions:PRTweenHasTweenedValueObserver operation:operation]; + + [[PRTween sharedInstance] performSelector:@selector(addTweenOperation:) withObject:operation afterDelay:0]; + return operation; + +} + + (PRTweenOperation *)lerp:(id)object property:(NSString *)property period:(PRTweenLerpPeriod *)period @@ -1032,6 +1058,12 @@ - (void)removeTweenOperation:(PRTweenOperation *)tweenOperation { } } +- (void)removeAllTweenOperations { + for (PRTweenOperation *tweenOperation in tweenOperations) { + [expiredTweenOperations addObject:tweenOperation]; + } +} + + (SEL)setterFromProperty:(NSString *)property { return NSSelectorFromString([NSString stringWithFormat:@"set%@:", [property stringByReplacingCharactersInRange:NSMakeRange(0, 1) withString:[[property substringToIndex:1] capitalizedString]]]); } From a08f19492daa2f17f629cf8b2d981b6483b1d4e5 Mon Sep 17 00:00:00 2001 From: Jon Gilkison Date: Fri, 11 Jan 2013 14:33:16 -0500 Subject: [PATCH 07/21] Fix for removing all running ops --- lib/PRTween.h | 1 + lib/PRTween.m | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/lib/PRTween.h b/lib/PRTween.h index 069baf5..e3fcfc5 100755 --- a/lib/PRTween.h +++ b/lib/PRTween.h @@ -173,6 +173,7 @@ typedef void (^PRTweenCompleteBlock)(); - (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)clearTweenOperations; #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; diff --git a/lib/PRTween.m b/lib/PRTween.m index e8b39af..ce8d459 100755 --- a/lib/PRTween.m +++ b/lib/PRTween.m @@ -624,6 +624,12 @@ - (void)removeTweenOperation:(PRTweenOperation *)tweenOperation { } } +- (void)clearTweenOperations +{ + for(PRTweenOperation *op in tweenOperations) + [expiredTweenOperations addObject:op]; +} + + (SEL)setterFromProperty:(NSString *)property { return NSSelectorFromString([NSString stringWithFormat:@"set%@:", [property stringByReplacingCharactersInRange:NSMakeRange(0, 1) withString:[[property substringToIndex:1] capitalizedString]]]); } @@ -721,6 +727,8 @@ - (void)dealloc { expiredTweenOperations = nil; [timer invalidate]; + + [super dealloc]; } @end From 6b91e45a57a969db59e7429a9d871c0438764c72 Mon Sep 17 00:00:00 2001 From: Jason Marziani Date: Wed, 6 Mar 2013 16:27:07 -0500 Subject: [PATCH 08/21] FIX: NSRunLoop issue where animations would not fire until after NSEventTrackingRunLoopMode completed, as when a UITableView or UIScrollView is scrolling. Added support for NSRunLoopCommonModes in calls to performSelector and with the NSTimer. --- lib/PRTween.m | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/lib/PRTween.m b/lib/PRTween.m index e8b39af..404d9db 100755 --- a/lib/PRTween.m +++ b/lib/PRTween.m @@ -277,7 +277,7 @@ + (PRTweenOperation *)tween:(id)object property:(NSString*)property from:(CGFloa operation.boundSetter = [PRTween setterFromProperty:property]; [operation addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedValue" options:NSKeyValueObservingOptionNew context:NULL]; - [[PRTween sharedInstance] performSelector:@selector(addTweenOperation:) withObject:operation afterDelay:0]; + [[PRTween sharedInstance] performSelector:@selector(addTweenOperation:) withObject:operation afterDelay:0 inModes:[NSArray arrayWithObject:NSRunLoopCommonModes]]; return operation; } @@ -293,7 +293,7 @@ + (PRTweenOperation *)tween:(CGFloat *)ref from:(CGFloat)from to:(CGFloat)to dur operation.boundRef = ref; [operation addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedValue" options:NSKeyValueObservingOptionNew context:NULL]; - [[PRTween sharedInstance] performSelector:@selector(addTweenOperation:) withObject:operation afterDelay:0]; + [[PRTween sharedInstance] performSelector:@selector(addTweenOperation:) withObject:operation afterDelay:0 inModes:[NSArray arrayWithObject:NSRunLoopCommonModes]]; return operation; } @@ -319,7 +319,7 @@ + (PRTweenOperation *)lerp:(id)object property:(NSString *)property period:(PRTw operation.boundSetter = [PRTween setterFromProperty:property]; [operation addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedLerp" options:NSKeyValueObservingOptionNew context:NULL]; - [[PRTween sharedInstance] performSelector:@selector(addTweenOperation:) withObject:operation afterDelay:0]; + [[PRTween sharedInstance] performSelector:@selector(addTweenOperation:) withObject:operation afterDelay:0 inModes:[NSArray arrayWithObject:NSRunLoopCommonModes]]; return operation; } @@ -338,7 +338,7 @@ + (PRTweenOperation *)tween:(id)object property:(NSString*)property from:(CGFloa operation.boundSetter = [PRTween setterFromProperty:property]; [operation addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedValue" options:NSKeyValueObservingOptionNew context:NULL]; - [[PRTween sharedInstance] performSelector:@selector(addTweenOperation:) withObject:operation afterDelay:0]; + [[PRTween sharedInstance] performSelector:@selector(addTweenOperation:) withObject:operation afterDelay:0 inModes:[NSArray arrayWithObject:NSRunLoopCommonModes]]; return operation; } @@ -354,7 +354,7 @@ + (PRTweenOperation *)tween:(CGFloat *)ref from:(CGFloat)from to:(CGFloat)to dur operation.boundRef = ref; [operation addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedValue" options:NSKeyValueObservingOptionNew context:NULL]; - [[PRTween sharedInstance] performSelector:@selector(addTweenOperation:) withObject:operation afterDelay:0]; + [[PRTween sharedInstance] performSelector:@selector(addTweenOperation:) withObject:operation afterDelay:0 inModes:[NSArray arrayWithObject:NSRunLoopCommonModes]]; return operation; } @@ -372,7 +372,7 @@ + (PRTweenOperation *)lerp:(id)object property:(NSString *)property period:(PRTw operation.boundSetter = [PRTween setterFromProperty:property]; [operation addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedLerp" options:NSKeyValueObservingOptionNew context:NULL]; - [[PRTween sharedInstance] performSelector:@selector(addTweenOperation:) withObject:operation afterDelay:0]; + [[PRTween sharedInstance] performSelector:@selector(addTweenOperation:) withObject:operation afterDelay:0 inModes:[NSArray arrayWithObject:NSRunLoopCommonModes]]; return operation; } @@ -426,6 +426,7 @@ - (id)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; } @@ -671,7 +672,7 @@ - (void)update { if (period != nil) { if (target != nil && selector != NULL) { - [target performSelector:selector withObject:period afterDelay:0]; + [target performSelector:selector withObject:period afterDelay:0 inModes:[NSArray arrayWithObject:NSRunLoopCommonModes]]; } // Check to see if blocks/GCD are supported @@ -692,7 +693,7 @@ - (void)update { // clean up expired tween operations for (__strong PRTweenOperation *tweenOperation in expiredTweenOperations) { - if (tweenOperation.completeSelector) [tweenOperation.target performSelector:tweenOperation.completeSelector withObject:nil afterDelay:0]; + 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) { From abee8aa7e18376fef718a58b65010ae51f381ee8 Mon Sep 17 00:00:00 2001 From: Gilles Guillemin Date: Thu, 7 Mar 2013 06:18:55 +0000 Subject: [PATCH 09/21] A bit of code cleaning/reformatting after last merge with upstream --- lib/PRTween.h | 493 +++++++++++--------- lib/PRTween.m | 1235 +++++++++++++++++++++++++------------------------ 2 files changed, 917 insertions(+), 811 deletions(-) diff --git a/lib/PRTween.h b/lib/PRTween.h index 2f7bfe0..dbc07d6 100755 --- a/lib/PRTween.h +++ b/lib/PRTween.h @@ -1,18 +1,21 @@ - #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)(); + +typedef void (^PRTweenCompleteBlock)(); + #endif enum { - PRTweenHasTweenedValueObserver = 1 << 0, - PRTweenHasTweenedLerpObserver = 1 << 1, + PRTweenHasTweenedValueObserver = 1 << 0, + PRTweenHasTweenedLerpObserver = 1 << 1, }; typedef NSUInteger PRTweenHasTweenedObserverOptions; @@ -25,27 +28,28 @@ typedef NSUInteger PRTweenHasTweenedObserverOptions; 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; +@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; + endValue:(CGFloat)anEndValue + duration:(CGFloat)duration; + (id)periodWithStartValue:(CGFloat)aStartValue - endValue:(CGFloat)anEndValue - duration:(CGFloat)duration - delay:(CGFloat)delay; + endValue:(CGFloat)anEndValue + duration:(CGFloat)duration + delay:(CGFloat)delay; @end @protocol PRTweenLerpPeriod -- (NSValue*)tweenedValueForProgress:(CGFloat)progress; +- (NSValue *)tweenedValueForProgress:(CGFloat)progress; + - (void)setProgress:(CGFloat)progress; @end @@ -56,314 +60,383 @@ typedef NSUInteger PRTweenHasTweenedObserverOptions; NSValue *tweenedLerp; } -@property (nonatomic, copy) NSValue *startLerp; -@property (nonatomic, copy) NSValue *endLerp; -@property (nonatomic, copy) 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; -+ (id)periodWithStartValue:(NSValue*)aStartValue - endValue:(NSValue*)anEndValue - duration:(CGFloat)duration - delay:(CGFloat)delay; ++ (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; + 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; + 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; + endCGSize:(CGSize)anEndSize + duration:(CGFloat)duration; + (id)periodWithStartCGSize:(CGSize)aStartSize - endCGSize:(CGSize)anEndSize - duration:(CGFloat)duration - delay:(CGFloat)delay; + 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; + NSObject *target; + SEL updateSelector; + SEL completeSelector; PRTweenTimingFunction timingFunction; - + CGFloat *boundRef; SEL boundGetter; SEL boundSetter; - + BOOL override; - - PRTweenHasTweenedObserverOptions observers; - + + PRTweenHasTweenedObserverOptions observers; + #if NS_BLOCKS_AVAILABLE - PRTweenUpdateBlock updateBlock; + PRTweenUpdateBlock updateBlock; PRTweenCompleteBlock completeBlock; #endif - - @private + +@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; +@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; +@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, assign) CGFloat *boundRef; +@property(nonatomic, retain) id boundObject; +@property(nonatomic) SEL boundGetter; +@property(nonatomic) SEL boundSetter; +@property(nonatomic) BOOL override; -@property (nonatomic) PRTweenHasTweenedObserverOptions observers; +@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; ++ (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; + ++ (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; + 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; + 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; + 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; + ++ (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; + 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; + 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; + 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; + ++ (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; + NSTimer *timer; CGFloat timeOffset; - + PRTweenTimingFunction defaultTimingFunction; - BOOL useBuiltInAnimationsWhenPossible; + BOOL useBuiltInAnimationsWhenPossible; } -@property (nonatomic, readonly) CGFloat timeOffset; -@property (nonatomic, assign) PRTweenTimingFunction defaultTimingFunction; -@property (nonatomic, assign) 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; + 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; + 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; + 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 *)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; + property:(NSString *)property + period:(PRTweenLerpPeriod *)period + timingFunction:(PRTweenTimingFunction)timingFunction + target:(NSObject *)target + completeSelector:(SEL)selector; -- (PRTweenOperation *)addTweenOperation:(PRTweenOperation*)operation; +- (PRTweenOperation *)addTweenOperation:(PRTweenOperation *)operation; - (PRTweenOperation *)addTweenPeriod:(PRTweenPeriod *)period - target:(NSObject *)target - selector:(SEL)selector; + target:(NSObject *)target + selector:(SEL)selector; - (PRTweenOperation *)addTweenPeriod:(PRTweenPeriod *)period - target:(NSObject *)target - selector:(SEL)selector - timingFunction:(PRTweenTimingFunction)timingFunction; + target:(NSObject *)target + selector:(SEL)selector + timingFunction:(PRTweenTimingFunction)timingFunction; + +- (void)removeTweenOperation:(PRTweenOperation *)tweenOperation; -- (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; + 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; + 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 - delay:(CGFloat)delay - timingFunction:(PRTweenTimingFunction)timingFunction - updateBlock:(PRTweenUpdateBlock)updateBlock - completeBlock:(PRTweenCompleteBlock)completeBlock; + 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; + 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; + updateBlock:(PRTweenUpdateBlock)updateBlock + completionBlock:(PRTweenCompleteBlock)completeBlock; - (PRTweenOperation *)addTweenPeriod:(PRTweenPeriod *)period - updateBlock:(PRTweenUpdateBlock)updateBlock - completionBlock:(PRTweenCompleteBlock)completionBlock - timingFunction:(PRTweenTimingFunction)timingFunction; + updateBlock:(PRTweenUpdateBlock)updateBlock + completionBlock:(PRTweenCompleteBlock)completionBlock + timingFunction:(PRTweenTimingFunction)timingFunction; + #endif @end diff --git a/lib/PRTween.m b/lib/PRTween.m index 61e559f..066467d 100755 --- a/lib/PRTween.m +++ b/lib/PRTween.m @@ -1,6 +1,3 @@ - -#import "PRTween.h" - #define kPRTweenFramerate 1.0/60 @implementation PRTweenPeriod @@ -12,32 +9,32 @@ @implementation PRTweenPeriod @synthesize startOffset; + (id)periodWithStartValue:(CGFloat)aStartValue - endValue:(CGFloat)anEndValue - duration:(CGFloat)duration { - + 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]; - + 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 { - + 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]; - + period.endValue = anEndValue; + period.duration = duration; + period.delay = delay; + period.startOffset = [[PRTween sharedInstance] timeOffset]; + return period; } @@ -48,33 +45,33 @@ @implementation PRTweenLerpPeriod @synthesize endLerp; @synthesize tweenedLerp; -+ (id)periodWithStartValue:(NSValue*)aStartValue - endValue:(NSValue*)anEndValue - duration:(CGFloat)duration { - ++ (id)periodWithStartValue:(NSValue *)aStartValue + endValue:(NSValue *)anEndValue + duration:(CGFloat)duration { + PRTweenLerpPeriod *period = [[self class] new]; - period.startLerp = aStartValue; + period.startLerp = aStartValue; period.tweenedLerp = aStartValue; - period.endLerp = anEndValue; - period.duration = duration; + 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 { - ++ (id)periodWithStartValue:(NSValue *)aStartValue + endValue:(NSValue *)anEndValue + duration:(CGFloat)duration + delay:(CGFloat)delay { + PRTweenLerpPeriod *period = [[self class] new]; - period.startLerp = aStartValue; + period.startLerp = aStartValue; period.tweenedLerp = aStartValue; - period.endLerp = anEndValue; - period.duration = duration; - period.delay = delay; + period.endLerp = anEndValue; + period.duration = duration; + period.delay = delay; period.startOffset = [[PRTween sharedInstance] timeOffset]; - + return period; } @@ -83,25 +80,33 @@ + (id)periodWithStartValue:(NSValue*)aStartValue @implementation PRTweenCGPointLerpPeriod + (id)periodWithStartCGPoint:(CGPoint)aStartPoint - endCGPoint:(CGPoint)anEndPoint - duration:(CGFloat)duration { - + 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]; } +- (CGPoint)startCGPoint { + return [self.startLerp CGPointValue]; +} + +- (CGPoint)tweenedCGPoint { + return [self.tweenedLerp CGPointValue]; +} + +- (CGPoint)endCGPoint { + return [self.endLerp CGPointValue]; +} + +- (NSValue *)tweenedValueForProgress:(CGFloat)progress { -- (NSValue*)tweenedValueForProgress:(CGFloat)progress { - - CGPoint startPoint = self.startCGPoint; - CGPoint endPoint = self.endCGPoint; - CGPoint distance = CGPointMake(endPoint.x - startPoint.x, endPoint.y - startPoint.y); + 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 { @@ -113,25 +118,33 @@ - (void)setProgress:(CGFloat)progress { @implementation PRTweenCGRectLerpPeriod + (id)periodWithStartCGRect:(CGRect)aStartRect - endCGRect:(CGRect)anEndRect - duration:(CGFloat)duration { - + 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]; } +- (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 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 { @@ -143,32 +156,40 @@ - (void)setProgress:(CGFloat)progress { @implementation PRTweenCGSizeLerpPeriod + (id)periodWithStartCGSize:(CGSize)aStartSize - endCGSize:(CGSize)anEndSize - duration:(CGFloat)duration { - + 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 { - + 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]; } +- (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 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 { @@ -178,7 +199,7 @@ - (void)setProgress:(CGFloat)progress { @end @interface PRTweenOperation () -@property (nonatomic) BOOL canUseBuiltAnimation; +@property(nonatomic) BOOL canUseBuiltAnimation; @end @implementation PRTweenOperation @@ -205,114 +226,99 @@ @implementation PRTweenOperation @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 { - + 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]; + 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 { - + 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]; + + 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 { - + 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]; + 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 { - + 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]; + 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.delay = delay; - return [PRTween lerp:object - property:property - period:period - timingFunction:timingFunction - updateBlock:updateBlock - completeBlock:completeBlock]; -} + property:(NSString *)property + from:(CGPoint)from + to:(CGPoint)to + duration:(CGFloat)duration + delay:(CGFloat)delay + 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 { - 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 @@ -320,75 +326,90 @@ + (PRTweenOperation *)lerp:(id)object property:(NSString *)property from:(CGPoin @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 { - + 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]; + 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 { - + 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]; + endCGRect:to + duration:duration]; period.delay = delay; return [PRTween lerp:object - property:property - period:period - timingFunction:timingFunction - target:target - completeSelector:selector]; + 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 { - + 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]; + 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 { + ++ (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 { - ++ (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 @@ -396,95 +417,96 @@ + (PRTweenOperation *)lerp:(id)object property:(NSString *)property from:(CGRect @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 { - + 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]; + 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 { - + 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]; + endCGSize:to + duration:duration]; period.delay = delay; return [PRTween lerp:object - property:property - period:period - timingFunction:timingFunction - target:target - completeSelector:selector]; + 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 { - + 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]; + 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 { - + 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]; + 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 PRTween *instance = nil; static NSArray *animationSelectorsForCoreAnimation = nil; -static NSArray *animationSelectorsForUIView = nil; +static NSArray *animationSelectorsForUIView = nil; @implementation PRTween @synthesize timeOffset; @@ -500,303 +522,306 @@ + (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 { - - PRTweenPeriod *period = [PRTweenPeriod periodWithStartValue:from - endValue:to - duration:duration]; + 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.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]; - [self addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedValue" observerOptions:PRTweenHasTweenedValueObserver operation:operation]; - + operation.boundObject = object; + operation.boundGetter = NSSelectorFromString([NSString stringWithFormat:@"%@", property]); + operation.boundSetter = [PRTween setterFromProperty:property]; + [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]; + 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.period = period; + operation.timingFunction = timingFunction; + operation.target = target; operation.completeSelector = selector; - operation.boundRef = ref; - [self addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedValue" observerOptions:PRTweenHasTweenedValueObserver operation:operation]; - + operation.boundRef = ref; + [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 - delay:(CGFloat)delay - timingFunction:(PRTweenTimingFunction)timingFunction - target:(NSObject*)target - completeSelector:(SEL)selector { - - PRTweenPeriod *period = [PRTweenPeriod periodWithStartValue:from - endValue:to - duration:duration - delay:delay]; + 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.period = period; + operation.timingFunction = timingFunction; + operation.target = target; operation.completeSelector = selector; - operation.boundRef = ref; - [self addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedValue" observerOptions:PRTweenHasTweenedValueObserver operation:operation]; - + operation.boundRef = ref; + [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 { - + 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]; + 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 { - + 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]; + 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 { - + 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.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]; - [self addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedLerp" observerOptions:PRTweenHasTweenedLerpObserver operation:operation]; - + operation.boundObject = object; + operation.boundGetter = NSSelectorFromString([NSString stringWithFormat:@"%@", property]); + operation.boundSetter = [PRTween setterFromProperty:property]; + [self addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedLerp" observerOptions:PRTweenHasTweenedLerpObserver operation:operation]; + [[PRTween sharedInstance] performSelector:@selector(addTweenOperation:) withObject:operation afterDelay:0]; 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]; + 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.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]; - [self addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedValue" observerOptions:PRTweenHasTweenedValueObserver operation:operation]; - + operation.updateBlock = updateBlock; + operation.completeBlock = completeBlock; + operation.boundObject = object; + operation.boundGetter = NSSelectorFromString([NSString stringWithFormat:@"%@", property]); + operation.boundSetter = [PRTween setterFromProperty:property]; + [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]; + 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.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]; - [self addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedValue" observerOptions:PRTweenHasTweenedValueObserver operation:operation]; - + operation.updateBlock = updateBlock; + operation.completeBlock = completeBlock; + operation.boundObject = object; + operation.boundGetter = NSSelectorFromString([NSString stringWithFormat:@"%@", property]); + operation.boundSetter = [PRTween setterFromProperty:property]; + [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]; + 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.period = period; operation.timingFunction = timingFunction; - operation.updateBlock = updateBlock; - operation.completeBlock = completeBlock; - operation.boundRef = ref; - [self addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedValue" observerOptions:PRTweenHasTweenedValueObserver operation:operation]; - + operation.updateBlock = updateBlock; + operation.completeBlock = completeBlock; + operation.boundRef = ref; + [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 - delay:(CGFloat)delay - timingFunction:(PRTweenTimingFunction)timingFunction - updateBlock:(PRTweenUpdateBlock)updateBlock - completeBlock:(PRTweenCompleteBlock)completeBlock { - - PRTweenPeriod *period = [PRTweenPeriod periodWithStartValue:from - endValue:to - duration:duration - delay:delay]; + 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.period = period; operation.timingFunction = timingFunction; - operation.updateBlock = updateBlock; - operation.completeBlock = completeBlock; - operation.boundRef = ref; - [self addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedValue" observerOptions:PRTweenHasTweenedValueObserver operation:operation]; - + operation.updateBlock = updateBlock; + operation.completeBlock = completeBlock; + operation.boundRef = ref; + [self addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedValue" observerOptions:PRTweenHasTweenedValueObserver operation:operation]; + [[PRTween sharedInstance] performSelector:@selector(addTweenOperation:) withObject:operation afterDelay:0]; return operation; - + } + (PRTweenOperation *)lerp:(id)object - property:(NSString *)property - period:(PRTweenLerpPeriod *)period - timingFunction:(PRTweenTimingFunction)timingFunction - updateBlock:(PRTweenUpdateBlock)updateBlock - completeBlock:(PRTweenCompleteBlock)completeBlock { - + 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.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]; - [self addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedLerp" observerOptions:PRTweenHasTweenedLerpObserver operation:operation]; - + operation.updateBlock = updateBlock; + operation.completeBlock = completeBlock; + operation.boundObject = object; + operation.boundGetter = NSSelectorFromString([NSString stringWithFormat:@"%@", property]); + operation.boundSetter = [PRTween setterFromProperty:property]; + [self addObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedLerp" observerOptions:PRTweenHasTweenedLerpObserver operation:operation]; + [[PRTween sharedInstance] performSelector:@selector(addTweenOperation:) withObject:operation afterDelay:0]; 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; + 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; - +- (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; - + 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]]; + 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]]; + NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[[operation.boundObject class] + instanceMethodSignatureForSelector:operation.boundSetter]]; [invocation setTarget:operation.boundObject]; [invocation setSelector:operation.boundSetter]; [invocation setArgument:&tweenedValue atIndex:2]; @@ -804,17 +829,17 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N } else if (operation.boundRef) { *operation.boundRef = tweenedValue; } - + } - + } - (id)init { self = [super init]; if (self != nil) { - tweenOperations = [[NSMutableArray alloc] init]; + tweenOperations = [[NSMutableArray alloc] init]; expiredTweenOperations = [[NSMutableArray alloc] init]; - timeOffset = 0; + timeOffset = 0; if (timer == nil) { timer = [NSTimer scheduledTimerWithTimeInterval:kPRTweenFramerate target:self selector:@selector(update) userInfo:nil repeats:YES]; } @@ -823,83 +848,84 @@ - (id)init { return self; } -- (PRTweenOperation*)addTweenOperation:(PRTweenOperation*)operation { - +- (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]; + @"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]; + @"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)) { + 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]; + + 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]; + 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]; + animation.toValue = [NSNumber numberWithFloat:operation.period.endValue]; } else { - PRTweenLerpPeriod *period = (PRTweenLerpPeriod*)operation.period; + PRTweenLerpPeriod *period = (PRTweenLerpPeriod *) operation.period; animation.fromValue = period.startLerp; - animation.toValue = period.endLerp; + animation.toValue = period.endLerp; } - + if (operation.timingFunction == &PRTweenTimingFunctionCAEaseIn) { animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]; } else if (operation.timingFunction == &PRTweenTimingFunctionCAEaseOut) { @@ -911,10 +937,10 @@ - (PRTweenOperation*)addTweenOperation:(PRTweenOperation*)operation { } else { animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault]; } - + [operation.boundObject setValue:animation.toValue forKeyPath:propertyFormatted]; [operation.boundObject addAnimation:animation forKey:@"PRTweenCAAnimation"]; - + goto complete; } } @@ -924,87 +950,93 @@ - (PRTweenOperation*)addTweenOperation:(PRTweenOperation*)operation { 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]; - + NSString *propertyFormatted = [[propertyUnformatted stringByReplacingCharactersInRange:NSMakeRange(0, 1) withString:[[propertyUnformatted substringToIndex:1] + lowercaseString]] substringToIndex:[propertyUnformatted length] - 1]; + NSValue *fromValue = nil; - NSValue *toValue = 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]; + toValue = [NSNumber numberWithFloat:operation.period.endValue]; } else { - PRTweenLerpPeriod *period = (PRTweenLerpPeriod*)operation.period; + PRTweenLerpPeriod *period = (PRTweenLerpPeriod *) operation.period; fromValue = period.startLerp; - toValue = period.endLerp; + 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]; + [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; } else if (operation.timingFunction == &PRTweenTimingFunctionUIViewLinear) { [UIView setAnimationCurve:UIViewAnimationCurveLinear]; } - + [operation.boundObject setValue:toValue forKeyPath:propertyFormatted]; [UIView commitAnimations]; - + goto complete; } } } - + } - -complete: + + complete: [tweenOperations addObject:operation]; return operation; } #if NS_BLOCKS_AVAILABLE -- (PRTweenOperation*)addTweenPeriod:(PRTweenPeriod *)period - updateBlock:(void (^)(PRTweenPeriod *period))updateBlock - completionBlock:(void (^)())completeBlock { + +- (PRTweenOperation *)addTweenPeriod:(PRTweenPeriod *)period + updateBlock:(void (^)(PRTweenPeriod *period))updateBlock + completionBlock:(void (^)())completeBlock { return [self addTweenPeriod:period updateBlock:updateBlock completionBlock:completeBlock timingFunction:self.defaultTimingFunction]; } -- (PRTweenOperation*)addTweenPeriod:(PRTweenPeriod *)period - updateBlock:(void (^)(PRTweenPeriod *period))anUpdateBlock - completionBlock:(void (^)())completeBlock - timingFunction:(PRTweenTimingFunction)timingFunction { - +- (PRTweenOperation *)addTweenPeriod:(PRTweenPeriod *)period + updateBlock:(void (^)(PRTweenPeriod *period))anUpdateBlock + completionBlock:(void (^)())completeBlock + timingFunction:(PRTweenTimingFunction)timingFunction { + PRTweenOperation *tweenOperation = [PRTweenOperation new]; - tweenOperation.period = period; + tweenOperation.period = period; tweenOperation.timingFunction = timingFunction; - tweenOperation.updateBlock = anUpdateBlock; - tweenOperation.completeBlock = completeBlock; + tweenOperation.updateBlock = anUpdateBlock; + tweenOperation.completeBlock = completeBlock; return [self addTweenOperation:tweenOperation]; - + } + #endif -- (PRTweenOperation*)addTweenPeriod:(PRTweenPeriod *)period target:(NSObject *)target selector:(SEL)selector { +- (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 *)addTweenPeriod:(PRTweenPeriod *)period + target:(NSObject *)target + selector:(SEL)selector + timingFunction:(PRTweenTimingFunction)timingFunction { + PRTweenOperation *tweenOperation = [PRTweenOperation new]; - tweenOperation.period = period; - tweenOperation.target = target; + tweenOperation.period = period; + tweenOperation.target = target; tweenOperation.timingFunction = timingFunction; tweenOperation.updateSelector = selector; - + return [self addTweenOperation:tweenOperation]; - + } - (void)removeTweenOperation:(PRTweenOperation *)tweenOperation { @@ -1016,37 +1048,38 @@ - (void)removeTweenOperation:(PRTweenOperation *)tweenOperation { } - (void)removeAllTweenOperations { - for (PRTweenOperation *tweenOperation in tweenOperations) { - [expiredTweenOperations addObject:tweenOperation]; - } + for (PRTweenOperation *tweenOperation in tweenOperations) { + [expiredTweenOperations addObject:tweenOperation]; + } } + (SEL)setterFromProperty:(NSString *)property { - return NSSelectorFromString([NSString stringWithFormat:@"set%@:", [property stringByReplacingCharactersInRange:NSMakeRange(0, 1) withString:[[property substringToIndex:1] capitalizedString]]]); + 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; + PRTweenLerpPeriod *lerpPeriod = (PRTweenLerpPeriod *) period; CGFloat progress = timingFunction(timeOffset - period.startOffset - period.delay, 0.0, 1.0, period.duration); [lerpPeriod setProgress:progress]; } else { @@ -1062,21 +1095,21 @@ - (void)update { 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]; + [target performSelector:selector withObject:period afterDelay:0]; } - + // 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) { @@ -1085,28 +1118,28 @@ - (void)update { } } } - + // clean up expired tween operations for (__strong PRTweenOperation *tweenOperation in expiredTweenOperations) { - + if (tweenOperation.completeSelector) [tweenOperation.target performSelector:tweenOperation.completeSelector withObject:nil afterDelay:0]; // Check to see if blocks/GCD are supported - if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_4_0) { + if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_4_0) { if (tweenOperation.completeBlock != NULL) { tweenOperation.completeBlock(); } } - if (tweenOperation.observers == PRTweenHasTweenedValueObserver) { + if (tweenOperation.observers == PRTweenHasTweenedValueObserver) { [tweenOperation removeObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedValue"]; - tweenOperation.observers = tweenOperation.observers & ~PRTweenHasTweenedValueObserver; - } + tweenOperation.observers = tweenOperation.observers & ~PRTweenHasTweenedValueObserver; + } - if (tweenOperation.observers == PRTweenHasTweenedLerpObserver) { + if (tweenOperation.observers == PRTweenHasTweenedLerpObserver) { [tweenOperation removeObserver:[PRTween sharedInstance] forKeyPath:@"period.tweenedLerp"]; - tweenOperation.observers = tweenOperation.observers & ~PRTweenHasTweenedLerpObserver; - } - + tweenOperation.observers = tweenOperation.observers & ~PRTweenHasTweenedLerpObserver; + } + [tweenOperations removeObject:tweenOperation]; tweenOperation = nil; } @@ -1114,7 +1147,7 @@ - (void)update { } - (void)dealloc { - tweenOperations = nil; + tweenOperations = nil; expiredTweenOperations = nil; [timer invalidate]; From 06c5494d61351e172f707c500ed0186d038cf1ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=A9=E8=BE=BA=E7=BE=85=E3=82=A8=E3=83=AB=E3=83=8D?= =?UTF-8?q?=E3=82=B9=E3=83=88?= Date: Thu, 3 Oct 2013 10:58:23 +0900 Subject: [PATCH 10/21] Fix unsequenced modification and access to variables' warnings --- lib/PRTweenTimingFunctions.m | 82 ++++++++++++++++++++++++------------ 1 file changed, 56 insertions(+), 26 deletions(-) diff --git a/lib/PRTweenTimingFunctions.m b/lib/PRTweenTimingFunctions.m index da42860..0e90f54 100755 --- a/lib/PRTweenTimingFunctions.m +++ b/lib/PRTweenTimingFunctions.m @@ -29,29 +29,39 @@ CGFloat PRTweenTimingFunctionLinear (CGFloat time, CGFloat begin, CGFloat change CGFloat PRTweenTimingFunctionBackOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { CGFloat s = 1.70158; - return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b; + 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; - return c*(t/=d)*t*((s+1)*t - s) + b; + 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) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b; - return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b; + 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)) { - return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b; + t-=(1.5/2.75); + return c*(7.5625*t*t + .75) + b; } else if (t < (2.5/2.75)) { - return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b; + t-=(2.25/2.75); + return c*(7.5625*t*t + .9375) + b; } else { - return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b; + t-=(2.625/2.75); + return c*(7.5625*t*t + .984375) + b; } } @@ -65,29 +75,35 @@ CGFloat PRTweenTimingFunctionBounceInOut (CGFloat t, CGFloat b, CGFloat c, CGFlo } CGFloat PRTweenTimingFunctionCircOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { - return c * sqrt(1 - (t=t/d-1)*t) + b; + t=t/d-1; + return c * sqrt(1 - t*t) + b; } CGFloat PRTweenTimingFunctionCircIn (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { - return -c * (sqrt(1 - (t/=d)*t) - 1) + b; + 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; - return c/2 * (sqrt(1 - (t-=2)*t) + 1) + b; + t-=2; + return c/2 * (sqrt(1 - t*t) + 1) + b; } CGFloat PRTweenTimingFunctionCubicOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { - return c*((t=t/d-1)*t*t + 1) + b; + t=t/d-1; + return c*(t*t*t + 1) + b; } CGFloat PRTweenTimingFunctionCubicIn (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { - return c*(t/=d)*t*t + b; + 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; - return c/2*((t-=2)*t*t + 2) + b; + t-=2; + return c/2*(t*t*t + 2) + b; } CGFloat PRTweenTimingFunctionElasticOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { @@ -105,7 +121,8 @@ CGFloat PRTweenTimingFunctionElasticIn (CGFloat t, CGFloat b, CGFloat c, CGFloat 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-=1)) * 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 )) + b; } CGFloat PRTweenTimingFunctionElasticInOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { @@ -114,8 +131,12 @@ CGFloat PRTweenTimingFunctionElasticInOut (CGFloat t, CGFloat b, CGFloat c, CGFl 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) return -.5*(a*pow(2,10*(t-=1)) * sin( (t*d-s)*(2*M_PI)/p )) + b; - return a*pow(2,-10*(t-=1)) * sin( (t*d-s)*(2*M_PI)/p )*.5 + c + b; + 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) { @@ -134,42 +155,51 @@ CGFloat PRTweenTimingFunctionExpoInOut (CGFloat t, CGFloat b, CGFloat c, CGFloat } CGFloat PRTweenTimingFunctionQuadOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { - return -c *(t/=d)*(t-2) + b; + t/=d; + return -c *t*(t-2) + b; } CGFloat PRTweenTimingFunctionQuadIn (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { - return c*(t/=d)*t + b; + 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; - return -c/2 * ((--t)*(t-2) - 1) + b; + t--; + return -c/2 * (t*(t-2) - 1) + b; } CGFloat PRTweenTimingFunctionQuartOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { - return -c * ((t=t/d-1)*t*t*t - 1) + b; + t=t/d-1; + return -c * (t*t*t*t - 1) + b; } CGFloat PRTweenTimingFunctionQuartIn (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { - return c*(t/=d)*t*t*t + b; + 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; - return -c/2 * ((t-=2)*t*t*t - 2) + b; + t-=2; + return -c/2 * (t*t*t*t - 2) + b; } CGFloat PRTweenTimingFunctionQuintOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { - return c*(t/=d)*t*t*t*t + b; + t/=d; + return c*t*t*t*t*t + b; } CGFloat PRTweenTimingFunctionQuintIn (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { - return c*((t=t/d-1)*t*t*t*t + 1) + b; + t=t/d-1; + return c*(t*t*t*t*t + 1) + 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; - return c/2*((t-=2)*t*t*t*t + 2) + b; + t-=2; + return c/2*(t*t*t*t*t + 2) + b; } CGFloat PRTweenTimingFunctionSineOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { From f5f22841b3d75ef53ea5f26e54c2b2036c754979 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=A9=E8=BE=BA=E7=BE=85=E3=82=A8=E3=83=AB=E3=83=8D?= =?UTF-8?q?=E3=82=B9=E3=83=88?= Date: Thu, 3 Oct 2013 11:00:23 +0900 Subject: [PATCH 11/21] Fix Analyzer warnings: branch evaluates garbage value --- lib/PRTweenTimingFunctions.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/PRTweenTimingFunctions.m b/lib/PRTweenTimingFunctions.m index 0e90f54..57106fd 100755 --- a/lib/PRTweenTimingFunctions.m +++ b/lib/PRTweenTimingFunctions.m @@ -108,7 +108,7 @@ CGFloat PRTweenTimingFunctionCubicInOut (CGFloat t, CGFloat b, CGFloat c, CGFloa CGFloat PRTweenTimingFunctionElasticOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { CGFloat p = d*.3; - CGFloat s, a; + 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); @@ -117,7 +117,7 @@ CGFloat PRTweenTimingFunctionElasticOut (CGFloat t, CGFloat b, CGFloat c, CGFloa CGFloat PRTweenTimingFunctionElasticIn (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { CGFloat p = d*.3; - CGFloat s, a; + 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); @@ -127,7 +127,7 @@ CGFloat PRTweenTimingFunctionElasticIn (CGFloat t, CGFloat b, CGFloat c, CGFloat CGFloat PRTweenTimingFunctionElasticInOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) { CGFloat p = d*(.3*1.5); - CGFloat s, a; + 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); From 9c0359f3f28043e2130624724701f169cebc297c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=A9=E8=BE=BA=E7=BE=85=E3=82=A8=E3=83=AB=E3=83=8D?= =?UTF-8?q?=E3=82=B9=E3=83=88?= Date: Thu, 3 Oct 2013 11:01:53 +0900 Subject: [PATCH 12/21] Apply Xcode 5 suggested setting changes to example project --- example/PRTween.xcodeproj/project.pbxproj | 5 ++--- .../xcshareddata/xcschemes/PRTween.xcscheme | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/example/PRTween.xcodeproj/project.pbxproj b/example/PRTween.xcodeproj/project.pbxproj index c3f124d..795c5ff 100644 --- a/example/PRTween.xcodeproj/project.pbxproj +++ b/example/PRTween.xcodeproj/project.pbxproj @@ -149,7 +149,7 @@ B25002B1139558F700670D11 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0440; + LastUpgradeCheck = 0500; ORGANIZATIONNAME = Jetsetter; }; buildConfigurationList = B25002B4139558F700670D11 /* Build configuration list for PBXProject "PRTween" */; @@ -228,7 +228,6 @@ B25002D9139558F700670D11 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_UNIVERSAL_IPHONE_OS)"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_OPTIMIZATION_LEVEL = 0; @@ -238,6 +237,7 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 4.3; + ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = 2; }; @@ -246,7 +246,6 @@ B25002DA139558F700670D11 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_UNIVERSAL_IPHONE_OS)"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_VERSION = com.apple.compilers.llvmgcc42; diff --git a/example/PRTween.xcodeproj/xcshareddata/xcschemes/PRTween.xcscheme b/example/PRTween.xcodeproj/xcshareddata/xcschemes/PRTween.xcscheme index 6e73091..994f5c0 100644 --- a/example/PRTween.xcodeproj/xcshareddata/xcschemes/PRTween.xcscheme +++ b/example/PRTween.xcodeproj/xcshareddata/xcschemes/PRTween.xcscheme @@ -1,6 +1,6 @@ From 590e3bc138fb368654794379008c3b80d18ead30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=A9=E8=BE=BA=E7=BE=85=E3=82=A8=E3=83=AB=E3=83=8D?= =?UTF-8?q?=E3=82=B9=E3=83=88?= Date: Thu, 3 Oct 2013 11:40:11 +0900 Subject: [PATCH 13/21] For now comment-out unimplemented method declaration --- lib/PRTween.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/PRTween.h b/lib/PRTween.h index dbc07d6..1ed5671 100755 --- a/lib/PRTween.h +++ b/lib/PRTween.h @@ -296,15 +296,15 @@ typedef NSUInteger PRTweenHasTweenedObserverOptions; 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; +//+ (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 From 7c4b3120cc342a33edc115566d6f65f6f389210a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=A9=E8=BE=BA=E7=BE=85=E3=82=A8=E3=83=AB=E3=83=8D?= =?UTF-8?q?=E3=82=B9=E3=83=88?= Date: Wed, 30 Oct 2013 17:38:59 +0900 Subject: [PATCH 14/21] Ignore *.xccheckout files --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 296d47a..267121b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ *.xcuserstate *.xcuserdatad -.DS_Store \ No newline at end of file +.DS_Store +*.xccheckout From 6f333ed1da577a9443a051a77f5725408444b667 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=A9=E8=BE=BA=E7=BE=85=E3=82=A8=E3=83=AB=E3=83=8D?= =?UTF-8?q?=E3=82=B9=E3=83=88?= Date: Wed, 30 Oct 2013 17:39:06 +0900 Subject: [PATCH 15/21] Add podspec --- PRTween.podspec | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 PRTween.podspec diff --git a/PRTween.podspec b/PRTween.podspec new file mode 100644 index 0000000..939e32b --- /dev/null +++ b/PRTween.podspec @@ -0,0 +1,15 @@ +Pod::Spec.new do |s| + s.name = 'PRTween' + s.version = '0.0.1' + s.license = 'BSD' + s.summary = 'PRTween is a lightweight tweening library built for iOS.' + s.homepage = 'https://github.com/dominikhofmann/PRTween' + s.author = { 'Dominik Hofmann' => '' } + + s.source = { :git => 'https://github.com/dominikhofmann/PRTween.git', :commit => 'a37330982a82e1f4f31f728af2cdb3fcfb223f6a' } + + s.description = 'While Apple has done an incredible job with UIView Animations and Core Animation, there are sometimes cases that are difficult to get around. PRTween is a great alternative if you\'d like to: Animate a property Core Animation won\'t allow you to Ensure that [someView layoutSubviews] is respected during an animation Tween arbitrary numerical values, such as sound volume, scroll position, a counter, or many others Define your timing curve as a function rather than a bezier with control points PRTween aims to be as simple as possible without sacrificing flexibility. In many cases, an animation may be as simple as: [PRTween tween:someView property:@"alpha" from:1 to:0 duration:3]; In order to promote simplicity, PRTween can be used as a drop-in replacement for most animations in your app. This means that in the case displayed above, the end result is identical to writing a UIView animation yourself.' + + s.platform = :ios + s.source_files = 'lib/*.{h,m}' +end From ebfb722175012df7dc3b70fa7563bbfbe7bf3dec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=A9=E8=BE=BA=E7=BE=85=E3=82=A8=E3=83=AB=E3=83=8D?= =?UTF-8?q?=E3=82=B9=E3=83=88?= Date: Wed, 30 Oct 2013 17:44:44 +0900 Subject: [PATCH 16/21] Update podspec --- PRTween.podspec | 1 + 1 file changed, 1 insertion(+) diff --git a/PRTween.podspec b/PRTween.podspec index 939e32b..49f4d32 100644 --- a/PRTween.podspec +++ b/PRTween.podspec @@ -11,5 +11,6 @@ Pod::Spec.new do |s| s.description = 'While Apple has done an incredible job with UIView Animations and Core Animation, there are sometimes cases that are difficult to get around. PRTween is a great alternative if you\'d like to: Animate a property Core Animation won\'t allow you to Ensure that [someView layoutSubviews] is respected during an animation Tween arbitrary numerical values, such as sound volume, scroll position, a counter, or many others Define your timing curve as a function rather than a bezier with control points PRTween aims to be as simple as possible without sacrificing flexibility. In many cases, an animation may be as simple as: [PRTween tween:someView property:@"alpha" from:1 to:0 duration:3]; In order to promote simplicity, PRTween can be used as a drop-in replacement for most animations in your app. This means that in the case displayed above, the end result is identical to writing a UIView animation yourself.' s.platform = :ios + s.requires_arc = true s.source_files = 'lib/*.{h,m}' end From 2e2b1c70d50e03083df35626ea8d3b99c5ad4435 Mon Sep 17 00:00:00 2001 From: Chris Harding Date: Fri, 29 Nov 2013 10:14:28 +0800 Subject: [PATCH 17/21] Added finished BOOL parameter to operation completion handler, so we can now detect if an operation was preempted using removeTweenOperation or removeAllTweenOperations. --- lib/PRTween.h | 7 ++++--- lib/PRTween.m | 23 +++++++++++++++++++---- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/lib/PRTween.h b/lib/PRTween.h index 1ed5671..2f367ef 100755 --- a/lib/PRTween.h +++ b/lib/PRTween.h @@ -1,5 +1,4 @@ -#import - +#import #import "PRTweenTimingFunctions.h" typedef CGFloat(*PRTweenTimingFunction)(CGFloat, CGFloat, CGFloat, CGFloat); @@ -9,7 +8,7 @@ typedef CGFloat(*PRTweenTimingFunction)(CGFloat, CGFloat, CGFloat, CGFloat); typedef void (^PRTweenUpdateBlock)(PRTweenPeriod *period); -typedef void (^PRTweenCompleteBlock)(); +typedef void (^PRTweenCompleteBlock)(BOOL finished); #endif @@ -127,6 +126,7 @@ typedef NSUInteger PRTweenHasTweenedObserverOptions; SEL boundSetter; BOOL override; + BOOL wasPreempted; PRTweenHasTweenedObserverOptions observers; @@ -155,6 +155,7 @@ typedef NSUInteger PRTweenHasTweenedObserverOptions; @property(nonatomic) SEL boundGetter; @property(nonatomic) SEL boundSetter; @property(nonatomic) BOOL override; +@property(nonatomic) BOOL wasPreempted; @property(nonatomic) PRTweenHasTweenedObserverOptions observers; diff --git a/lib/PRTween.m b/lib/PRTween.m index d34da0d..b654374 100755 --- a/lib/PRTween.m +++ b/lib/PRTween.m @@ -217,6 +217,7 @@ @implementation PRTweenOperation @synthesize boundSetter; @synthesize canUseBuiltAnimation; @synthesize override; +@synthesize wasPreempted; @synthesize observers; #if NS_BLOCKS_AVAILABLE @@ -544,6 +545,7 @@ + (PRTweenOperation *)tween:(id)object 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]; @@ -568,6 +570,7 @@ + (PRTweenOperation *)tween:(CGFloat *)ref 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]]; @@ -594,6 +597,7 @@ + (PRTweenOperation *)tween:(CGFloat *)ref 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]]; @@ -643,6 +647,7 @@ + (PRTweenOperation *)lerp:(id)object 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]]; @@ -672,6 +677,7 @@ + (PRTweenOperation *)tween:(id)object 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]; @@ -701,6 +707,7 @@ + (PRTweenOperation *)tween:(id)object 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]; @@ -725,6 +732,7 @@ + (PRTweenOperation *)tween:(CGFloat *)ref 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]]; @@ -751,6 +759,7 @@ + (PRTweenOperation *)tween:(CGFloat *)ref 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]]; @@ -774,6 +783,7 @@ + (PRTweenOperation *)lerp:(id)object 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]]; @@ -1004,13 +1014,13 @@ - (PRTweenOperation *)addTweenOperation:(PRTweenOperation *)operation { - (PRTweenOperation *)addTweenPeriod:(PRTweenPeriod *)period updateBlock:(void (^)(PRTweenPeriod *period))updateBlock - completionBlock:(void (^)())completeBlock { + 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 (^)())completeBlock + completionBlock:(void (^)(BOOL finished))completeBlock timingFunction:(PRTweenTimingFunction)timingFunction { PRTweenOperation *tweenOperation = [PRTweenOperation new]; @@ -1018,6 +1028,7 @@ - (PRTweenOperation *)addTweenPeriod:(PRTweenPeriod *)period tweenOperation.timingFunction = timingFunction; tweenOperation.updateBlock = anUpdateBlock; tweenOperation.completeBlock = completeBlock; + tweenOperation.wasPreempted = NO; return [self addTweenOperation:tweenOperation]; } @@ -1038,6 +1049,7 @@ - (PRTweenOperation *)addTweenPeriod:(PRTweenPeriod *)period tweenOperation.target = target; tweenOperation.timingFunction = timingFunction; tweenOperation.updateSelector = selector; + tweenOperation.wasPreempted = NO; return [self addTweenOperation:tweenOperation]; @@ -1046,6 +1058,7 @@ - (PRTweenOperation *)addTweenPeriod:(PRTweenPeriod *)period - (void)removeTweenOperation:(PRTweenOperation *)tweenOperation { if (tweenOperation != nil) { if ([tweenOperations containsObject:tweenOperation]) { + tweenOperation.wasPreempted = YES; [expiredTweenOperations addObject:tweenOperation]; } } @@ -1053,6 +1066,7 @@ - (void)removeTweenOperation:(PRTweenOperation *)tweenOperation { - (void)removeAllTweenOperations { for (PRTweenOperation *tweenOperation in tweenOperations) { + tweenOperation.wasPreempted = YES; [expiredTweenOperations addObject:tweenOperation]; } } @@ -1062,7 +1076,7 @@ + (SEL)setterFromProperty:(NSString *)property { capitalizedString]]]); } -- (void)update { +- (void) update { timeOffset += kPRTweenFramerate; for (PRTweenOperation *tweenOperation in tweenOperations) { @@ -1127,10 +1141,11 @@ - (void)update { 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.completeBlock(!tweenOperation.wasPreempted); } } From 78f4953ba7bf61eeaa7108058b9addf1cbbfe0e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=A9=E8=BE=BA=E7=BE=85=E3=82=A8=E3=83=AB=E3=83=8D?= =?UTF-8?q?=E3=82=B9=E3=83=88?= Date: Mon, 2 Dec 2013 11:51:23 +0900 Subject: [PATCH 18/21] Add Travis CI configuration --- .travis.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..96f0d19 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,11 @@ + +language: objective-c + +before_install: +- gem install cocoapods + +script: +- pod repo update --silent +- pod lib lint +- cd example +- xctool -project PRTween.xcodeproj -scheme 'PRTween' -configuration Release -sdk iphonesimulator -arch i386 build From e6c458dd81e1eccc54994fc38a3b18bcd64cd803 Mon Sep 17 00:00:00 2001 From: Chris Harding Date: Mon, 2 Dec 2013 10:54:56 +0800 Subject: [PATCH 19/21] Updated example app to use new completion block type. --- example/PRTweenExampleViewController.m | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/example/PRTweenExampleViewController.m b/example/PRTweenExampleViewController.m index b1f5e70..71b4d9c 100644 --- a/example/PRTweenExampleViewController.m +++ b/example/PRTweenExampleViewController.m @@ -75,8 +75,9 @@ - (IBAction)verboseTapped { - (IBAction)blockTapped { activeTweenOperation = [[PRTween sharedInstance] addTweenPeriod:[PRTweenPeriod periodWithStartValue:0 endValue:904 duration:1.5] updateBlock:^(PRTweenPeriod *period) { testView.frame = CGRectMake(0, period.tweenedValue, 100, 100); - } completionBlock:^(void) { - NSLog(@"Completed tween"); + } completionBlock:^(BOOL finished) { + if (finished) NSLog(@"Completed tween"); + else NSLog(@"Tween preempted before completion."); }]; } From 942449d7db9c3df6ef2fdb9c4791f9e6e80ba9f2 Mon Sep 17 00:00:00 2001 From: Chris Harding Date: Tue, 6 May 2014 20:02:48 +0800 Subject: [PATCH 20/21] Added linear damping timing function. --- lib/PRTween.h | 1 + lib/PRTweenLinearDamping.h | 7 +++ lib/PRTweenLinearDamping.m | 110 +++++++++++++++++++++++++++++++++++++ 3 files changed, 118 insertions(+) create mode 100644 lib/PRTweenLinearDamping.h create mode 100644 lib/PRTweenLinearDamping.m diff --git a/lib/PRTween.h b/lib/PRTween.h index 2f367ef..09e9663 100755 --- a/lib/PRTween.h +++ b/lib/PRTween.h @@ -1,5 +1,6 @@ #import #import "PRTweenTimingFunctions.h" +#import "PRTweenLinearDamping.h" typedef CGFloat(*PRTweenTimingFunction)(CGFloat, CGFloat, CGFloat, CGFloat); diff --git a/lib/PRTweenLinearDamping.h b/lib/PRTweenLinearDamping.h new file mode 100644 index 0000000..fd2eb0a --- /dev/null +++ b/lib/PRTweenLinearDamping.h @@ -0,0 +1,7 @@ +// Created by Chris Harding on 06/05/2014. +// Copyright (c) 2014 Chris Harding. All rights reserved. +// + +#import + +CGFloat PRTweenTimingFunctionLinearDamping (CGFloat, CGFloat, CGFloat, CGFloat); diff --git a/lib/PRTweenLinearDamping.m b/lib/PRTweenLinearDamping.m new file mode 100644 index 0000000..186aa32 --- /dev/null +++ b/lib/PRTweenLinearDamping.m @@ -0,0 +1,110 @@ +// Created by Chris Harding on 06/05/2014. +// Copyright (c) 2014 Chris Harding. All rights reserved. +// + +#import "PRTweenLinearDamping.h" + +#define DAMPING_RATIO 0.6 +#define NATURAL_FREQUENCY 15.0 + +CGFloat PRTweenTimingFunctionLinearDamping (CGFloat t, CGFloat b, CGFloat c, CGFloat d) +{ + /* + Solution obtained from http://mathworld.wolfram.com/DampedSimpleHarmonicMotionOverdamping.html + + x(t) = Ae^{\gamma_+ t} + Be^{\gamma_- t} + + where ''A'' and ''B'' are determined by the initial conditions of the system: + + A = x(0)+\frac{\gamma_+x(0)-\dot{x}(0)}{\gamma_--\gamma_+} + B = -\frac{\gamma_+x(0)-\dot{x}(0)}{\gamma_--\gamma_+} + + For our system, the inital conditions are: + + x(0) = -c + + After calculating x(t), the return value required is: + + b + c + x(t) + + Note that duration is ignored - the system is instead determined by its damping ratio and natural frequency. + + */ + + // Input vars (these should be variable) + CGFloat dampingRatio = DAMPING_RATIO; + CGFloat naturalFrequency = NATURAL_FREQUENCY; + + // Shorthand + CGFloat w0 = naturalFrequency; + CGFloat L = dampingRatio; + + // Constants + const CGFloat epsilon = 0.0001; + + // Return value + CGFloat x; + + /* + If dampingRatio >1.0 then the system is over-damped. We do not currently handle this case since its value in an animation is limited. + */ + if (dampingRatio > 1.0 + epsilon) x = 0; + + + /* + If dampingRatio == 1.0 then the system is critically damped. A critically damped system converges to zero as fast as possible without oscillating. + + Solution for x(t) : + + x(t) = (A+Bt)\,e^{-\omega_0 t} + + A = x(0) + B = \dot{x}(0)+\omega_0x(0) + + */ + else if (dampingRatio > 1.0 - epsilon) { + + CGFloat w0t = w0 * t; + x = -c * (1 + w0t) * exp(-w0t); + } + + + /* + If dampingRatio < 1.0 then the system is under-damped. In this situation, the system will oscillate at the natural damped frequency: + + \omega_\mathrm{d} = \omega_0 \sqrt{1 - \zeta^2 } + + Solution for x(t) : + + x(t) = e^{- \zeta \omega_0 t} (A \cos\,(\omega_\mathrm{d}\,t) + B \sin\,(\omega_\mathrm{d}\,t )) + + A = x(0) + B = \frac{1}{\omega_\mathrm{d}}(\zeta\omega_0x(0)+\dot{x}(0)) + + */ + else { + + + CGFloat dampedFrequency = w0 * sqrt(1.0 - L*L); + CGFloat wd = dampedFrequency; + CGFloat wdt = wd * t; + + CGFloat A = -c; + CGFloat B = (L * w0 * -c) / wd; + + x = exp(-L * w0 * t) * (A*cos(wdt) + B*sin(wdt)); + + } + + /* + To ensure the function ends correctly, we snap it to the final value once it reches a certain threshold. + */ + if (fabs(x) < epsilon) x = 0.0; + + /* + After calculating x(t), the return value required is: b + c + x(t) + */ + return b + c + x; +}; + + From 3f9d3fde6c34a11145c5b8fd2695877e9d851d94 Mon Sep 17 00:00:00 2001 From: Ernesto Rivera Date: Wed, 22 Oct 2014 15:05:06 +0900 Subject: [PATCH 21/21] Update podspec and bump version --- PRTween.podspec | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/PRTween.podspec b/PRTween.podspec index 49f4d32..c52425e 100644 --- a/PRTween.podspec +++ b/PRTween.podspec @@ -1,16 +1,19 @@ + Pod::Spec.new do |s| + s.name = 'PRTween' - s.version = '0.0.1' + s.version = '0.1.0' s.license = 'BSD' s.summary = 'PRTween is a lightweight tweening library built for iOS.' s.homepage = 'https://github.com/dominikhofmann/PRTween' s.author = { 'Dominik Hofmann' => '' } - s.source = { :git => 'https://github.com/dominikhofmann/PRTween.git', :commit => 'a37330982a82e1f4f31f728af2cdb3fcfb223f6a' } + s.source = { :git => "https://github.com/PRTween/PRTween.git", :tag => "#{s.version}" } s.description = 'While Apple has done an incredible job with UIView Animations and Core Animation, there are sometimes cases that are difficult to get around. PRTween is a great alternative if you\'d like to: Animate a property Core Animation won\'t allow you to Ensure that [someView layoutSubviews] is respected during an animation Tween arbitrary numerical values, such as sound volume, scroll position, a counter, or many others Define your timing curve as a function rather than a bezier with control points PRTween aims to be as simple as possible without sacrificing flexibility. In many cases, an animation may be as simple as: [PRTween tween:someView property:@"alpha" from:1 to:0 duration:3]; In order to promote simplicity, PRTween can be used as a drop-in replacement for most animations in your app. This means that in the case displayed above, the end result is identical to writing a UIView animation yourself.' s.platform = :ios s.requires_arc = true s.source_files = 'lib/*.{h,m}' + end