Skip to content
This repository was archived by the owner on Aug 30, 2023. It is now read-only.

Commit 5e6b649

Browse files
authoredNov 29, 2017
Use objcType to identify the value types. (#73)
* Use objcType to identify the value types. This makes it much more scalable to support arbitrary key paths. * Review feedback. * Explicit checks.
1 parent 74c0d53 commit 5e6b649

File tree

1 file changed

+29
-13
lines changed

1 file changed

+29
-13
lines changed
 

‎src/private/CABasicAnimation+MotionAnimator.m

+29-13
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,32 @@
2020

2121
#import <UIKit/UIKit.h>
2222

23+
#pragma mark - Private
24+
25+
static BOOL IsNumberValue(id someValue) {
26+
return [someValue isKindOfClass:[NSNumber class]];
27+
}
28+
29+
static BOOL IsCGPointType(id someValue) {
30+
if ([someValue isKindOfClass:[NSValue class]]) {
31+
NSValue *asValue = (NSValue *)someValue;
32+
const char *objCType = @encode(CGPoint);
33+
return strncmp(asValue.objCType, objCType, strlen(objCType)) == 0;
34+
}
35+
return NO;
36+
}
37+
38+
static BOOL IsCGSizeType(id someValue) {
39+
if ([someValue isKindOfClass:[NSValue class]]) {
40+
NSValue *asValue = (NSValue *)someValue;
41+
const char *objCType = @encode(CGSize);
42+
return strncmp(asValue.objCType, objCType, strlen(objCType)) == 0;
43+
}
44+
return NO;
45+
}
46+
47+
#pragma mark - Public
48+
2349
CABasicAnimation *MDMAnimationFromTiming(MDMMotionTiming timing, CGFloat timeScaleFactor) {
2450
CABasicAnimation *animation;
2551
switch (timing.curve.type) {
@@ -67,17 +93,7 @@ void MDMConfigureAnimation(CABasicAnimation *animation,
6793
return; // Nothing to do here.
6894
}
6995

70-
// We can't infer the from/to value types from the animation if the values are NSValue types, so
71-
// we map known key paths to their data types here:
72-
static NSSet *sizeKeyPaths = nil;
73-
static NSSet *positionKeyPaths = nil;
74-
static dispatch_once_t onceToken;
75-
dispatch_once(&onceToken, ^{
76-
sizeKeyPaths = [NSSet setWithArray:@[@"bounds.size", @"shadowOffset"]];
77-
positionKeyPaths = [NSSet setWithArray:@[@"position", @"anchorPoint"]];
78-
});
79-
80-
if ([animation.toValue isKindOfClass:[NSNumber class]]) {
96+
if (IsNumberValue(animation.toValue)) {
8197
// Non-additive animations animate along a direct path between fromValue and toValue, regardless
8298
// of the model layer. Additive animations, on the other hand, animate towards the layer's model
8399
// value by applying this formula:
@@ -166,7 +182,7 @@ void MDMConfigureAnimation(CABasicAnimation *animation,
166182
springAnimation.initialVelocity = absoluteInitialVelocity / displacement;
167183
}
168184

169-
} else if ([sizeKeyPaths containsObject:animation.keyPath]) {
185+
} else if (IsCGSizeType(animation.toValue)) {
170186
CGSize from = [animation.fromValue CGSizeValue];
171187
CGSize to = [animation.toValue CGSizeValue];
172188
CGSize additiveDisplacement = CGSizeMake(from.width - to.width, from.height - to.height);
@@ -198,7 +214,7 @@ void MDMConfigureAnimation(CABasicAnimation *animation,
198214
springAnimation.initialVelocity = absoluteInitialVelocity / displacement;
199215
}
200216

201-
} else if ([positionKeyPaths containsObject:animation.keyPath]) {
217+
} else if (IsCGPointType(animation.toValue)) {
202218
CGPoint from = [animation.fromValue CGPointValue];
203219
CGPoint to = [animation.toValue CGPointValue];
204220
CGPoint additiveDisplacement = CGPointMake(from.x - to.x, from.y - to.y);

0 commit comments

Comments
 (0)
This repository has been archived.