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

Commit ee19fda

Browse files
authored
Move private APIs to the private folder. (#17)
* Move MDMSimulatorAnimationDragCoefficient to a private folder. This will allow the API to be reused across source files within the project. * Also move timingFunctionWithControlPoints to the private folder. * Move more APIs to private. * Docs. * Add missing import. * Fixes.
1 parent ccdffd5 commit ee19fda

9 files changed

+295
-120
lines changed

src/MDMMotionAnimator.m

+7-120
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,9 @@
1818

1919
#import <UIKit/UIKit.h>
2020

21-
#if TARGET_IPHONE_SIMULATOR
22-
UIKIT_EXTERN float UIAnimationDragCoefficient(void); // UIKit private drag coefficient.
23-
#endif
24-
25-
static CGFloat simulatorAnimationDragCoefficient(void) {
26-
#if TARGET_IPHONE_SIMULATOR
27-
return UIAnimationDragCoefficient();
28-
#else
29-
return 1.0;
30-
#endif
31-
}
32-
33-
static CAMediaTimingFunction* timingFunctionWithControlPoints(CGFloat controlPoints[4]);
34-
static NSArray* coerceUIKitValuesToCoreAnimationValues(NSArray *values);
35-
static CABasicAnimation *animationFromTiming(MDMMotionTiming timing, CGFloat timeScaleFactor);
36-
static void makeAnimationAdditive(CABasicAnimation *animation);
21+
#import "private/CABasicAnimation+MotionAnimator.h"
22+
#import "private/MDMUIKitValueCoercion.h"
23+
#import "private/MDMDragCoefficient.h"
3724

3825
@implementation MDMMotionAnimator {
3926
NSMutableArray *_tracers;
@@ -65,7 +52,7 @@ - (void)animateWithTiming:(MDMMotionTiming)timing
6552
if (_shouldReverseValues) {
6653
values = [[values reverseObjectEnumerator] allObjects];
6754
}
68-
values = coerceUIKitValuesToCoreAnimationValues(values);
55+
values = MDMCoerceUIKitValuesToCoreAnimationValues(values);
6956

7057
if (timing.duration == 0 || timing.curve.type == MDMMotionCurveTypeInstant) {
7158
[layer setValue:[values lastObject] forKeyPath:keyPath];
@@ -75,8 +62,8 @@ - (void)animateWithTiming:(MDMMotionTiming)timing
7562
return;
7663
}
7764

78-
CGFloat timeScaleFactor = simulatorAnimationDragCoefficient() * _timeScaleFactor;
79-
CABasicAnimation *animation = animationFromTiming(timing, timeScaleFactor);
65+
CGFloat timeScaleFactor = MDMSimulatorAnimationDragCoefficient() * _timeScaleFactor;
66+
CABasicAnimation *animation = MDMAnimationFromTiming(timing, timeScaleFactor);
8067

8168
if (animation) {
8269
animation.keyPath = keyPath;
@@ -97,7 +84,7 @@ - (void)animateWithTiming:(MDMMotionTiming)timing
9784

9885
if (![animation.fromValue isEqual:animation.toValue]) {
9986
if (self.additive) {
100-
makeAnimationAdditive(animation);
87+
MDMMakeAnimationAdditive(animation);
10188
}
10289

10390
if (timing.delay != 0) {
@@ -137,103 +124,3 @@ - (void)addCoreAnimationTracer:(void (^)(CALayer *, CAAnimation *))tracer {
137124

138125
@end
139126

140-
static CAMediaTimingFunction* timingFunctionWithControlPoints(CGFloat controlPoints[4]) {
141-
return [CAMediaTimingFunction functionWithControlPoints:(float)controlPoints[0]
142-
:(float)controlPoints[1]
143-
:(float)controlPoints[2]
144-
:(float)controlPoints[3]];
145-
}
146-
147-
static NSArray* coerceUIKitValuesToCoreAnimationValues(NSArray *values) {
148-
if ([[values firstObject] isKindOfClass:[UIColor class]]) {
149-
NSMutableArray *convertedArray = [NSMutableArray arrayWithCapacity:values.count];
150-
for (UIColor *color in values) {
151-
[convertedArray addObject:(id)color.CGColor];
152-
}
153-
values = convertedArray;
154-
155-
} else if ([[values firstObject] isKindOfClass:[UIBezierPath class]]) {
156-
NSMutableArray *convertedArray = [NSMutableArray arrayWithCapacity:values.count];
157-
for (UIBezierPath *bezierPath in values) {
158-
[convertedArray addObject:(id)bezierPath.CGPath];
159-
}
160-
values = convertedArray;
161-
}
162-
return values;
163-
}
164-
165-
static CABasicAnimation *animationFromTiming(MDMMotionTiming timing, CGFloat timeScaleFactor) {
166-
CABasicAnimation *animation;
167-
switch (timing.curve.type) {
168-
case MDMMotionCurveTypeInstant:
169-
animation = nil;
170-
break;
171-
172-
case MDMMotionCurveTypeDefault:
173-
case MDMMotionCurveTypeBezier:
174-
animation = [CABasicAnimation animation];
175-
animation.timingFunction = timingFunctionWithControlPoints(timing.curve.data);
176-
animation.duration = timing.duration * timeScaleFactor;
177-
break;
178-
179-
case MDMMotionCurveTypeSpring: {
180-
#pragma clang diagnostic push
181-
// CASpringAnimation is a private API on iOS 8 - we're able to make use of it because we're
182-
// linking against the public API on iOS 9+.
183-
#pragma clang diagnostic ignored "-Wpartial-availability"
184-
CASpringAnimation *spring = [CASpringAnimation animation];
185-
#pragma clang diagnostic pop
186-
spring.mass = timing.curve.data[MDMSpringMotionCurveDataIndexMass];
187-
spring.stiffness = timing.curve.data[MDMSpringMotionCurveDataIndexTension];
188-
spring.damping = timing.curve.data[MDMSpringMotionCurveDataIndexFriction];
189-
190-
// This API is only available on iOS 9+
191-
if ([spring respondsToSelector:@selector(settlingDuration)]) {
192-
spring.duration = spring.settlingDuration;
193-
} else {
194-
spring.duration = timing.duration;
195-
}
196-
animation = spring;
197-
break;
198-
}
199-
}
200-
return animation;
201-
}
202-
203-
static void makeAnimationAdditive(CABasicAnimation *animation) {
204-
static NSSet *sizeKeyPaths = nil;
205-
static NSSet *positionKeyPaths = nil;
206-
static dispatch_once_t onceToken;
207-
dispatch_once(&onceToken, ^{
208-
sizeKeyPaths = [NSSet setWithArray:@[@"bounds.size"]];
209-
210-
positionKeyPaths = [NSSet setWithArray:@[@"position",
211-
@"anchorPoint"]];
212-
});
213-
214-
if ([animation.toValue isKindOfClass:[NSNumber class]]) {
215-
CGFloat currentValue = (CGFloat)[animation.fromValue doubleValue];
216-
CGFloat delta = currentValue - (CGFloat)[animation.toValue doubleValue];
217-
animation.fromValue = @(delta);
218-
animation.toValue = @0;
219-
animation.additive = true;
220-
221-
} else if ([sizeKeyPaths containsObject:animation.keyPath]) {
222-
CGSize currentValue = [animation.fromValue CGSizeValue];
223-
CGSize destinationValue = [animation.toValue CGSizeValue];
224-
CGSize delta = CGSizeMake(currentValue.width - destinationValue.width,
225-
currentValue.height - destinationValue.height);
226-
animation.fromValue = [NSValue valueWithCGSize:delta];
227-
animation.toValue = [NSValue valueWithCGSize:CGSizeZero];
228-
animation.additive = true;
229-
230-
} else if ([positionKeyPaths containsObject:animation.keyPath]) {
231-
CGPoint currentValue = [animation.fromValue CGPointValue];
232-
CGPoint destinationValue = [animation.toValue CGPointValue];
233-
CGPoint delta = CGPointMake(currentValue.x - destinationValue.x,
234-
currentValue.y - destinationValue.y);
235-
animation.fromValue = [NSValue valueWithCGPoint:delta];
236-
animation.toValue = [NSValue valueWithCGPoint:CGPointZero];
237-
animation.additive = true;
238-
}
239-
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
Copyright 2017-present The Material Motion Authors. All Rights Reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
#import <MotionInterchange/MotionInterchange.h>
18+
19+
#import <Foundation/Foundation.h>
20+
#import <CoreGraphics/CoreGraphics.h>
21+
#import <QuartzCore/QuartzCore.h>
22+
23+
// Returns a basic animation configured with the provided timing and scale factor.
24+
FOUNDATION_EXPORT
25+
CABasicAnimation *MDMAnimationFromTiming(MDMMotionTiming timing, CGFloat timeScaleFactor);
26+
27+
// Attemps to configure the provided animation to be additive.
28+
// Not all animation value types are supported. If an animation's value type was not supported,
29+
// the animation will not be modified.
30+
FOUNDATION_EXPORT void MDMMakeAnimationAdditive(CABasicAnimation *animation);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/*
2+
Copyright 2017-present The Material Motion Authors. All Rights Reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
#import "CABasicAnimation+MotionAnimator.h"
18+
19+
#import "CAMediaTimingFunction+MotionAnimator.h"
20+
21+
#import <UIKit/UIKit.h>
22+
23+
CABasicAnimation *MDMAnimationFromTiming(MDMMotionTiming timing, CGFloat timeScaleFactor) {
24+
CABasicAnimation *animation;
25+
switch (timing.curve.type) {
26+
case MDMMotionCurveTypeInstant:
27+
animation = nil;
28+
break;
29+
30+
case MDMMotionCurveTypeDefault:
31+
case MDMMotionCurveTypeBezier:
32+
animation = [CABasicAnimation animation];
33+
animation.timingFunction = MDMTimingFunctionWithControlPoints(timing.curve.data);
34+
animation.duration = timing.duration * timeScaleFactor;
35+
break;
36+
37+
case MDMMotionCurveTypeSpring: {
38+
#pragma clang diagnostic push
39+
// CASpringAnimation is a private API on iOS 8 - we're able to make use of it because we're
40+
// linking against the public API on iOS 9+.
41+
#pragma clang diagnostic ignored "-Wpartial-availability"
42+
CASpringAnimation *spring = [CASpringAnimation animation];
43+
#pragma clang diagnostic pop
44+
spring.mass = timing.curve.data[MDMSpringMotionCurveDataIndexMass];
45+
spring.stiffness = timing.curve.data[MDMSpringMotionCurveDataIndexTension];
46+
spring.damping = timing.curve.data[MDMSpringMotionCurveDataIndexFriction];
47+
48+
// This API is only available on iOS 9+
49+
if ([spring respondsToSelector:@selector(settlingDuration)]) {
50+
spring.duration = spring.settlingDuration;
51+
} else {
52+
spring.duration = timing.duration;
53+
}
54+
animation = spring;
55+
break;
56+
}
57+
}
58+
return animation;
59+
}
60+
61+
void MDMMakeAnimationAdditive(CABasicAnimation *animation) {
62+
static NSSet *sizeKeyPaths = nil;
63+
static NSSet *positionKeyPaths = nil;
64+
static dispatch_once_t onceToken;
65+
dispatch_once(&onceToken, ^{
66+
sizeKeyPaths = [NSSet setWithArray:@[@"bounds.size"]];
67+
68+
positionKeyPaths = [NSSet setWithArray:@[@"position",
69+
@"anchorPoint"]];
70+
});
71+
72+
if ([animation.toValue isKindOfClass:[NSNumber class]]) {
73+
CGFloat currentValue = (CGFloat)[animation.fromValue doubleValue];
74+
CGFloat delta = currentValue - (CGFloat)[animation.toValue doubleValue];
75+
animation.fromValue = @(delta);
76+
animation.toValue = @0;
77+
animation.additive = true;
78+
79+
} else if ([sizeKeyPaths containsObject:animation.keyPath]) {
80+
CGSize currentValue = [animation.fromValue CGSizeValue];
81+
CGSize destinationValue = [animation.toValue CGSizeValue];
82+
CGSize delta = CGSizeMake(currentValue.width - destinationValue.width,
83+
currentValue.height - destinationValue.height);
84+
animation.fromValue = [NSValue valueWithCGSize:delta];
85+
animation.toValue = [NSValue valueWithCGSize:CGSizeZero];
86+
animation.additive = true;
87+
88+
} else if ([positionKeyPaths containsObject:animation.keyPath]) {
89+
CGPoint currentValue = [animation.fromValue CGPointValue];
90+
CGPoint destinationValue = [animation.toValue CGPointValue];
91+
CGPoint delta = CGPointMake(currentValue.x - destinationValue.x,
92+
currentValue.y - destinationValue.y);
93+
animation.fromValue = [NSValue valueWithCGPoint:delta];
94+
animation.toValue = [NSValue valueWithCGPoint:CGPointZero];
95+
animation.additive = true;
96+
}
97+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
Copyright 2017-present The Material Motion Authors. All Rights Reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
#import <Foundation/Foundation.h>
18+
#import <CoreGraphics/CoreGraphics.h>
19+
#import <QuartzCore/QuartzCore.h>
20+
21+
// Returns a timing function with the given control points.
22+
FOUNDATION_EXPORT
23+
CAMediaTimingFunction* MDMTimingFunctionWithControlPoints(CGFloat controlPoints[4]);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
Copyright 2017-present The Material Motion Authors. All Rights Reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
#import "CAMediaTimingFunction+MotionAnimator.h"
18+
19+
CAMediaTimingFunction* MDMTimingFunctionWithControlPoints(CGFloat controlPoints[4]) {
20+
return [CAMediaTimingFunction functionWithControlPoints:(float)controlPoints[0]
21+
:(float)controlPoints[1]
22+
:(float)controlPoints[2]
23+
:(float)controlPoints[3]];
24+
}

src/private/MDMDragCoefficient.h

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*
2+
Copyright 2017-present The Material Motion Authors. All Rights Reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
#import <Foundation/Foundation.h>
18+
#import <CoreGraphics/CoreGraphics.h>
19+
20+
// Returns the simulator drag coefficient when being run in the simulator, or 1.0 otherwise.
21+
FOUNDATION_EXTERN CGFloat MDMSimulatorAnimationDragCoefficient(void);

src/private/MDMDragCoefficient.m

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
Copyright 2017-present The Material Motion Authors. All Rights Reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
#import "MDMDragCoefficient.h"
18+
19+
#import <UIKit/UIKit.h>
20+
21+
#if TARGET_IPHONE_SIMULATOR
22+
UIKIT_EXTERN float UIAnimationDragCoefficient(void); // UIKit private drag coefficient.
23+
#endif
24+
25+
CGFloat MDMSimulatorAnimationDragCoefficient(void) {
26+
#if TARGET_IPHONE_SIMULATOR
27+
return UIAnimationDragCoefficient();
28+
#else
29+
return 1.0;
30+
#endif
31+
}

0 commit comments

Comments
 (0)