Browse Source

refactored shared element transitions (#2783)

yogevbd 6 years ago
parent
commit
48a0d2ba7e
No account linked to committer's email address

+ 3
- 4
lib/ios/RNNAnimatedView.h View File

1
 #import <UIKit/UIKit.h>
1
 #import <UIKit/UIKit.h>
2
-#import "RNNTransitionStateHolder.h"
3
 #import "RNNViewLocation.h"
2
 #import "RNNViewLocation.h"
4
 #import "VICMAImageView.h"
3
 #import "VICMAImageView.h"
5
 
4
 
6
-@class RNNViewLocation;
7
-@class RNNTransitionStateHolder;
5
+
8
 @interface RNNAnimatedView : UIView
6
 @interface RNNAnimatedView : UIView
9
 
7
 
10
--(instancetype)initWithTransition:(RNNTransitionStateHolder*)transition andLocation:(RNNViewLocation*)location andIsBackButton:(BOOL)backButton;
8
+-(instancetype)initFromElement:(RNNElementView*)fromElement toElement:(RNNElementView*)toElement andLocation:(RNNViewLocation*)location andIsBackButton:(BOOL)backButton startAlpha:(CGFloat)startAlpha endAlpha:(CGFloat)endAlpha;
11
 +(UIViewContentMode)contentModefromString:(NSString*)resizeMode;
9
 +(UIViewContentMode)contentModefromString:(NSString*)resizeMode;
10
+
12
 @end
11
 @end

+ 11
- 15
lib/ios/RNNAnimatedView.m View File

3
 
3
 
4
 @implementation RNNAnimatedView
4
 @implementation RNNAnimatedView
5
 
5
 
6
--(instancetype)initWithTransition:(RNNTransitionStateHolder*)transition andLocation:(RNNViewLocation*)location andIsBackButton:(BOOL)backButton {
6
+-(instancetype)initFromElement:(RNNElementView*)fromElement toElement:(RNNElementView*)toElement andLocation:(RNNViewLocation*)location andIsBackButton:(BOOL)backButton startAlpha:(CGFloat)startAlpha endAlpha:(CGFloat)endAlpha {
7
 	UIView* animatedView = nil;
7
 	UIView* animatedView = nil;
8
 	if (backButton) {
8
 	if (backButton) {
9
-		if ([self elementIsImage:transition.fromElement]) {
10
-			animatedView = [self createImageAnimatedView:animatedView fromElement:transition.fromElement toElement:transition.toElement];
9
+		if ([self elementIsImage:fromElement]) {
10
+			animatedView = [self createImageAnimatedView:animatedView fromElement:fromElement toElement:toElement];
11
 		} else {
11
 		} else {
12
-			if (transition.toElement) {
13
-				animatedView = [[transition.toElement subviews][0] snapshotViewAfterScreenUpdates:NO];
12
+			if (toElement) {
13
+				animatedView = [[toElement subviews][0] snapshotViewAfterScreenUpdates:NO];
14
 			} else {
14
 			} else {
15
-				animatedView = [[transition.fromElement subviews][0] snapshotViewAfterScreenUpdates:NO];
15
+				animatedView = [[fromElement subviews][0] snapshotViewAfterScreenUpdates:NO];
16
 			}
16
 			}
17
 		}
17
 		}
18
-		[self assignStyle:animatedView withSize:location.toSize center:location.toCenter andAlpha:transition.endAlpha];
18
+		[self assignStyle:animatedView withSize:location.toSize center:location.toCenter andAlpha:endAlpha];
19
 	} else {
19
 	} else {
20
-		if ([self elementIsImage:transition.fromElement]) {
21
-			animatedView = [self createImageAnimatedView:animatedView fromElement:transition.fromElement toElement:transition.fromElement];
20
+		if ([self elementIsImage:fromElement]) {
21
+			animatedView = [self createImageAnimatedView:animatedView fromElement:fromElement toElement:fromElement];
22
 		} else {
22
 		} else {
23
-			if (transition.isFromVC) {
24
-				animatedView = [[transition.fromElement subviews][0] snapshotViewAfterScreenUpdates:NO];
25
-			} else {
26
-				animatedView = [[transition.fromElement subviews][0] snapshotViewAfterScreenUpdates:YES];
27
-			}
23
+			animatedView = [[fromElement subviews][0] snapshotViewAfterScreenUpdates:YES];
28
 		}
24
 		}
29
-		[self assignStyle:animatedView withSize:location.fromSize center:location.fromCenter andAlpha:transition.startAlpha];
25
+		[self assignStyle:animatedView withSize:location.fromSize center:location.fromCenter andAlpha:startAlpha];
30
 	}
26
 	}
31
 	return (RNNAnimatedView*)animatedView;
27
 	return (RNNAnimatedView*)animatedView;
32
 }
28
 }

lib/ios/RNNTransitionOptions.h → lib/ios/RNNAnimationOptions.h View File

1
 #import "RNNOptions.h"
1
 #import "RNNOptions.h"
2
 
2
 
3
-@interface RNNTransitionOptions : RNNOptions
3
+@interface RNNAnimationOptions : RNNOptions
4
 
4
 
5
 @property (nonatomic, strong) NSArray* animations;
5
 @property (nonatomic, strong) NSArray* animations;
6
 @property (nonatomic, strong) NSNumber* duration;
6
 @property (nonatomic, strong) NSNumber* duration;

lib/ios/RNNTransitionOptions.m → lib/ios/RNNAnimationOptions.m View File

1
-#import "RNNTransitionOptions.h"
1
+#import "RNNAnimationOptions.h"
2
 
2
 
3
 #define DEFAULT_DURATION @(0.7)
3
 #define DEFAULT_DURATION @(0.7)
4
 #define DEFAULT_SPRING_VELOCITY @(0.8)
4
 #define DEFAULT_SPRING_VELOCITY @(0.8)
5
 #define DEFAULT_SPRING_DAMPING @(0.85)
5
 #define DEFAULT_SPRING_DAMPING @(0.85)
6
 
6
 
7
-@implementation RNNTransitionOptions
7
+@implementation RNNAnimationOptions
8
 
8
 
9
 - (instancetype)initWithDict:(NSDictionary *)dict {
9
 - (instancetype)initWithDict:(NSDictionary *)dict {
10
 	if (!dict[@"animations"]) {
10
 	if (!dict[@"animations"]) {

+ 2
- 3
lib/ios/RNNAnimator.h View File

1
 #import <Foundation/Foundation.h>
1
 #import <Foundation/Foundation.h>
2
 #import <UIKit/UIKit.h>
2
 #import <UIKit/UIKit.h>
3
-#import "RNNElementView.h"
4
-#import "RNNTransitionOptions.h"
3
+#import "RNNAnimationOptions.h"
5
 
4
 
6
 @interface RNNAnimator : NSObject <UIViewControllerAnimatedTransitioning>
5
 @interface RNNAnimator : NSObject <UIViewControllerAnimatedTransitioning>
7
 
6
 
8
--(instancetype)initWithTransitionOptions:(RNNTransitionOptions *)transitionOptions;
7
+-(instancetype)initWithTransitionOptions:(RNNAnimationOptions *)transitionOptions;
9
 
8
 
10
 @end
9
 @end

+ 22
- 70
lib/ios/RNNAnimator.m View File

1
-#import <React/RCTRedBox.h>
2
 #import "RNNAnimator.h"
1
 #import "RNNAnimator.h"
3
-#import "RNNElementView.h"
4
-#import "RNNInteractivePopAnimator.h"
5
-#import "VICMAImageView.h"
6
-#import "RNNTransitionStateHolder.h"
7
-#import "RNNElementFinder.h"
8
-#import "RNNViewLocation.h"
9
-#import "RNNAnimatedView.h"
2
+#import "RNNTransition.h"
10
 
3
 
11
 @interface  RNNAnimator()
4
 @interface  RNNAnimator()
12
-@property (nonatomic, strong) RNNTransitionOptions* transitionOptions;
13
-@property (nonatomic, strong) RNNInteractivePopAnimator* interactivePopAnimator;
5
+@property (nonatomic, strong) RNNAnimationOptions* transitionOptions;
14
 @property (nonatomic) BOOL backButton;
6
 @property (nonatomic) BOOL backButton;
15
 @property (nonatomic, strong) UIViewController* fromVC;
7
 @property (nonatomic, strong) UIViewController* fromVC;
16
 @property (nonatomic, strong) UIViewController* toVC;
8
 @property (nonatomic, strong) UIViewController* toVC;
18
 
10
 
19
 @implementation RNNAnimator
11
 @implementation RNNAnimator
20
 
12
 
21
--(instancetype)initWithTransitionOptions:(RNNTransitionOptions *)transitionOptions {
13
+-(instancetype)initWithTransitionOptions:(RNNAnimationOptions *)transitionOptions {
22
 	self = [super init];
14
 	self = [super init];
23
 	if (transitionOptions) {
15
 	if (transitionOptions) {
24
 		[self setupTransition:transitionOptions];
16
 		[self setupTransition:transitionOptions];
29
 	return self;
21
 	return self;
30
 }
22
 }
31
 
23
 
32
--(void)setupTransition:(RNNTransitionOptions *)transitionOptions {
24
+-(void)setupTransition:(RNNAnimationOptions *)transitionOptions {
33
 	self.transitionOptions = transitionOptions;
25
 	self.transitionOptions = transitionOptions;
34
 	if (!transitionOptions.animations) {
26
 	if (!transitionOptions.animations) {
35
 		[[NSException exceptionWithName:NSInvalidArgumentException reason:@"No animations" userInfo:nil] raise];
27
 		[[NSException exceptionWithName:NSInvalidArgumentException reason:@"No animations" userInfo:nil] raise];
38
 	self.backButton = false;
30
 	self.backButton = false;
39
 }
31
 }
40
 
32
 
41
--(NSArray*)prepareSharedElementTransition:(NSArray*)RNNSharedElementsToVC
42
-						andfromVCElements:(NSArray*)RNNSharedElementsFromVC
43
-						withComponentView:(UIView*)componentView {
33
+-(NSArray*)prepareSharedElementTransitionWithComponentView:(UIView*)componentView {
44
 	NSMutableArray* transitions = [NSMutableArray new];
34
 	NSMutableArray* transitions = [NSMutableArray new];
45
 	for (NSDictionary* transition in self.transitionOptions.animations) {
35
 	for (NSDictionary* transition in self.transitionOptions.animations) {
46
 		RNNTransitionStateHolder* transitionStateHolder = [[RNNTransitionStateHolder alloc] initWithTransition:transition];
36
 		RNNTransitionStateHolder* transitionStateHolder = [[RNNTransitionStateHolder alloc] initWithTransition:transition];
47
-		RNNElementFinder* elementFinder = [[RNNElementFinder alloc] initWithToVC:self.toVC andfromVC:self.fromVC];
48
-		[elementFinder findElementsInTransition:transitionStateHolder];
49
-		RNNViewLocation* animatedViewLocations = [[RNNViewLocation alloc] initWithTransition:transitionStateHolder andVC:self.fromVC];
50
-		RNNAnimatedView* animatedView = [[RNNAnimatedView alloc] initWithTransition:transitionStateHolder andLocation:animatedViewLocations andIsBackButton:self.backButton];
51
-		transitionStateHolder.locations = animatedViewLocations;
52
-		[componentView addSubview:animatedView];
53
-		[componentView bringSubviewToFront:animatedView];
54
-		transitionStateHolder.animatedView = animatedView;
55
-		[transitions addObject:transitionStateHolder];
56
-		if (transitionStateHolder.isSharedElementTransition) {
57
-			[transitionStateHolder.toElement setHidden: YES];
58
-		}
59
-		[transitionStateHolder.fromElement setHidden:YES];
37
+		RNNTransition* transition = [[RNNTransition alloc] initFromVC:self.fromVC toVC:self.toVC transitionOptions:transitionStateHolder isBackButton:self.backButton];
38
+
39
+		[componentView addSubview:transition.animatedView];
40
+		[componentView bringSubviewToFront:transition.animatedView];
41
+		
42
+		[transitions addObject:transition];
60
 	}
43
 	}
44
+	
61
 	return transitions;
45
 	return transitions;
62
 }
46
 }
63
 
47
 
64
 -(void)animateTransitions:(NSArray*)transitions {
48
 -(void)animateTransitions:(NSArray*)transitions {
65
-	for (RNNTransitionStateHolder* transition in transitions ) {
66
-		[UIView animateWithDuration:transition.duration delay:transition.startDelay usingSpringWithDamping:transition.springDamping initialSpringVelocity:transition.springVelocity options:UIViewAnimationOptionCurveEaseOut  animations:^{
67
-			RNNAnimatedView* animatedView = transition.animatedView;
68
-			if (!self.backButton) {
69
-				[self setAnimatedViewFinalProperties:animatedView toElement:transition.toElement fromElement:transition.fromElement isSharedElementTransition:transition.isSharedElementTransition withTransform:transition.locations.transform withCenter:transition.locations.toCenter andAlpha:transition.endAlpha];
70
-			} else {
71
-				[self setAnimatedViewFinalProperties:animatedView toElement:transition.fromElement fromElement:transition.fromElement isSharedElementTransition:transition.isSharedElementTransition withTransform:transition.locations.transformBack withCenter:transition.locations.fromCenter andAlpha:transition.startAlpha];
72
-			}
49
+	for (RNNTransition* transition in transitions ) {
50
+		[UIView animateWithDuration:transition.options.duration delay:transition.options.startDelay usingSpringWithDamping:transition.options.springDamping initialSpringVelocity:transition.options.springVelocity options:UIViewAnimationOptionCurveEaseOut  animations:^{
51
+			[transition setAnimatedViewFinalProperties];
73
 		} completion:^(BOOL finished) {
52
 		} completion:^(BOOL finished) {
74
 
53
 
75
 		}];
54
 		}];
76
 	}
55
 	}
77
 }
56
 }
78
 
57
 
79
--(void)setAnimatedViewFinalProperties:(RNNAnimatedView*)animatedView toElement:(RNNElementView*)toElement fromElement:(RNNElementView*)fromElement isSharedElementTransition:(BOOL)isShared withTransform:(CGAffineTransform)transform withCenter:(CGPoint)center andAlpha:(double)alpha {
80
-	animatedView.alpha = alpha;
81
-	animatedView.center = center;
82
-	animatedView.transform = transform;
83
-	if (isShared) {
84
-		if ([[fromElement subviews][0] isKindOfClass:[UIImageView class]]) {
85
-			animatedView.contentMode = UIViewContentModeScaleAspectFill;
86
-			if ([toElement resizeMode]){
87
-				animatedView.contentMode = [RNNAnimatedView contentModefromString:[toElement resizeMode]];
88
-			}
89
-		}
90
-	}
91
-}
92
-
93
-
94
--(void)animateComplition:(NSArray*)transitions fromVCSnapshot:(UIView*)fromSnapshot andTransitioningContext:(id<UIViewControllerContextTransitioning>)transitionContext {
58
+-(void)animateCompletion:(NSArray*)transitions fromVCSnapshot:(UIView*)fromSnapshot andTransitioningContext:(id<UIViewControllerContextTransitioning>)transitionContext {
95
 	[UIView animateWithDuration:[self transitionDuration:transitionContext] delay:0 usingSpringWithDamping:[self.transitionOptions.springDamping doubleValue] initialSpringVelocity:[self.transitionOptions.springVelocity doubleValue] options:UIViewAnimationOptionCurveEaseOut  animations:^{
59
 	[UIView animateWithDuration:[self transitionDuration:transitionContext] delay:0 usingSpringWithDamping:[self.transitionOptions.springDamping doubleValue] initialSpringVelocity:[self.transitionOptions.springVelocity doubleValue] options:UIViewAnimationOptionCurveEaseOut  animations:^{
96
 				self.toVC.view.alpha = 1;
60
 				self.toVC.view.alpha = 1;
97
 			} completion:^(BOOL finished) {
61
 			} completion:^(BOOL finished) {
98
-				for (RNNTransitionStateHolder* transition in transitions ) {
99
-					[transition.fromElement setHidden:NO];
100
-					if (transition.isSharedElementTransition) {
101
-						[transition.toElement setHidden:NO];
102
-					}
103
-					RNNAnimatedView* animtedView = transition.animatedView;
104
-					[animtedView removeFromSuperview];
105
-					
106
-					if (transition.interactivePop) {
107
-						self.interactivePopAnimator = [[RNNInteractivePopAnimator alloc] initWithTopView:transition.toElement andBottomView:transition.fromElement andOriginFrame:transition.locations.fromFrame andViewController:self.toVC];
108
-						UIPanGestureRecognizer* gesture = [[UIPanGestureRecognizer alloc] initWithTarget:self.interactivePopAnimator
109
-																								  action:@selector(handleGesture:)];
110
-						[transition.toElement addGestureRecognizer:gesture];
111
-					}
62
+				for (RNNTransition* transition in transitions ) {
63
+					[transition transitionCompleted];
112
 				}
64
 				}
65
+				
113
 				[fromSnapshot removeFromSuperview];
66
 				[fromSnapshot removeFromSuperview];
114
 				if (![transitionContext transitionWasCancelled]) {
67
 				if (![transitionContext transitionWasCancelled]) {
115
 					self.toVC.view.alpha = 1;
68
 					self.toVC.view.alpha = 1;
135
 	[componentView addSubview:fromSnapshot];
88
 	[componentView addSubview:fromSnapshot];
136
 	[componentView addSubview:toVC.view];
89
 	[componentView addSubview:toVC.view];
137
 	toVC.view.alpha = 0;
90
 	toVC.view.alpha = 0;
138
-	NSArray* onlyForTesting = @[];
139
-	NSArray* onlyForTesting2 = @[];
140
-	NSArray* transitions = [self prepareSharedElementTransition:onlyForTesting andfromVCElements:onlyForTesting2 withComponentView:componentView];
141
-	[self animateComplition:transitions fromVCSnapshot:fromSnapshot andTransitioningContext:transitionContext];
91
+	
92
+	NSArray* transitions = [self prepareSharedElementTransitionWithComponentView:componentView];
93
+	[self animateCompletion:transitions fromVCSnapshot:fromSnapshot andTransitioningContext:transitionContext];
142
 	[self animateTransitions:transitions];
94
 	[self animateTransitions:transitions];
143
 }
95
 }
144
 
96
 

+ 1
- 1
lib/ios/RNNCommandsHandler.m View File

77
 	}];
77
 	}];
78
 	
78
 	
79
 	NSDictionary* animationData = options[@"customTransition"];
79
 	NSDictionary* animationData = options[@"customTransition"];
80
-	RNNTransitionOptions* transitionOptions = [[RNNTransitionOptions alloc] initWithDict:animationData];
80
+	RNNAnimationOptions* transitionOptions = [[RNNAnimationOptions alloc] initWithDict:animationData];
81
 	
81
 	
82
 	if (transitionOptions){
82
 	if (transitionOptions){
83
 		if (transitionOptions.animations) {
83
 		if (transitionOptions.animations) {

+ 3
- 7
lib/ios/RNNElementFinder.h View File

1
 #import <Foundation/Foundation.h>
1
 #import <Foundation/Foundation.h>
2
 #import "RNNElementView.h"
2
 #import "RNNElementView.h"
3
-#import "RNNTransitionStateHolder.h"
4
 
3
 
5
 @interface RNNElementFinder : NSObject
4
 @interface RNNElementFinder : NSObject
6
 
5
 
7
-@property (nonatomic, strong) NSArray* toVCTransitionElements;
8
-@property (nonatomic, strong) NSArray* fromVCTransitionElements;
6
+- (instancetype)initWithToVC:(UIViewController *)toVC andfromVC:(UIViewController *)fromVC;
7
+
8
+- (RNNElementView *)findElementForId:(NSString *)elementId;
9
 
9
 
10
--(instancetype)initWithToVC:(UIViewController*)toVC andfromVC:(UIViewController*)fromVC;
11
--(NSArray*)findRNNElementViews:(UIView*)view;
12
--(RNNElementView*)findViewToAnimate:(NSArray*)RNNTransitionElementViews withId:(NSString*)elementId;
13
--(void)findElementsInTransition:(RNNTransitionStateHolder*)transitionStateHolder;
14
 @end
10
 @end

+ 24
- 21
lib/ios/RNNElementFinder.m View File

1
 #import "RNNElementFinder.h"
1
 #import "RNNElementFinder.h"
2
 
2
 
3
+@interface RNNElementFinder ()
4
+
5
+@property (nonatomic, strong) NSArray* toVCTransitionElements;
6
+@property (nonatomic, strong) NSArray* fromVCTransitionElements;
7
+
8
+@end
9
+
3
 @implementation RNNElementFinder 
10
 @implementation RNNElementFinder 
4
 
11
 
5
--(instancetype)initWithToVC:(UIViewController*)toVC andfromVC:(UIViewController*)fromVC {
12
+- (instancetype)initWithToVC:(UIViewController *)toVC andfromVC:(UIViewController *)fromVC {
6
 	self = [super init];
13
 	self = [super init];
14
+	
7
 	self.toVCTransitionElements = [self findRNNElementViews:toVC.view];
15
 	self.toVCTransitionElements = [self findRNNElementViews:toVC.view];
8
 	self.fromVCTransitionElements = [self findRNNElementViews:fromVC.view];
16
 	self.fromVCTransitionElements = [self findRNNElementViews:fromVC.view];
17
+	
9
 	return self;
18
 	return self;
10
 }
19
 }
11
 
20
 
12
--(RNNElementView*)findViewToAnimate:(NSArray*)RNNTransitionElementViews withId:(NSString*)elementId{
21
+- (RNNElementView *)findViewToAnimate:(NSArray *)RNNTransitionElementViews withId:(NSString *)elementId{
13
 	for (RNNElementView* view in RNNTransitionElementViews) {
22
 	for (RNNElementView* view in RNNTransitionElementViews) {
14
 		if ([view.elementId isEqualToString:elementId]){
23
 		if ([view.elementId isEqualToString:elementId]){
15
 			return view;
24
 			return view;
18
 	return nil;
27
 	return nil;
19
 }
28
 }
20
 
29
 
21
--(NSArray*)findRNNElementViews:(UIView*)view{
30
+- (NSArray *)findRNNElementViews:(UIView*)view {
22
 	NSMutableArray* elementViews = [NSMutableArray new];
31
 	NSMutableArray* elementViews = [NSMutableArray new];
23
-	for(UIView *aView in view.subviews){
24
-		if([aView isMemberOfClass:[RNNElementView class]]){
32
+	for (UIView *aView in view.subviews) {
33
+		if([aView isMemberOfClass:[RNNElementView class]]) {
25
 			[elementViews addObject:aView];
34
 			[elementViews addObject:aView];
26
 		} else{
35
 		} else{
27
 			if ([aView subviews]) {
36
 			if ([aView subviews]) {
29
 			}
38
 			}
30
 		}
39
 		}
31
 	}
40
 	}
41
+	
32
 	return elementViews;
42
 	return elementViews;
33
 }
43
 }
34
 
44
 
35
--(void)findElementsInTransition:(RNNTransitionStateHolder*)transitionStateHolder {
36
-	if ([self findViewToAnimate:self.toVCTransitionElements withId:transitionStateHolder.fromId]) {
37
-		transitionStateHolder.fromElement = [self findViewToAnimate:self.toVCTransitionElements withId:transitionStateHolder.fromId];
38
-		transitionStateHolder.isFromVC = false;
39
-	} else if ([self findViewToAnimate:self.fromVCTransitionElements withId:transitionStateHolder.fromId]){
40
-		transitionStateHolder.fromElement = [self findViewToAnimate:self.fromVCTransitionElements withId:transitionStateHolder.fromId];
41
-		transitionStateHolder.isFromVC = true;
42
-	} else {
43
-		[[NSException exceptionWithName:NSInvalidArgumentException reason:[NSString stringWithFormat:@"elementId %@ does not exist", transitionStateHolder.fromId] userInfo:nil] raise];
44
-	}
45
-	if (transitionStateHolder.toId) {
46
-		if ([self findViewToAnimate:self.toVCTransitionElements withId:transitionStateHolder.toId]) {
47
-			transitionStateHolder.toElement = [self findViewToAnimate:self.toVCTransitionElements withId:transitionStateHolder.toId];
48
-		} else if ([self findViewToAnimate:self.fromVCTransitionElements withId:transitionStateHolder.toId]){
49
-			transitionStateHolder.toElement = [self findViewToAnimate:self.fromVCTransitionElements withId:transitionStateHolder.toId];
45
+- (RNNElementView *)findElementForId:(NSString *)elementId {
46
+	if (elementId) {
47
+		if ([self findViewToAnimate:self.toVCTransitionElements withId:elementId]) {
48
+			return [self findViewToAnimate:self.toVCTransitionElements withId:elementId];
49
+		} else if ([self findViewToAnimate:self.fromVCTransitionElements withId:elementId]){
50
+			return [self findViewToAnimate:self.fromVCTransitionElements withId:elementId];
50
 		} else {
51
 		} else {
51
-			[[NSException exceptionWithName:NSInvalidArgumentException reason:[NSString stringWithFormat:@"elementId %@ does not exist", transitionStateHolder.toId] userInfo:nil] raise];
52
+			[[NSException exceptionWithName:NSInvalidArgumentException reason:[NSString stringWithFormat:@"elementId %@ does not exist", elementId] userInfo:nil] raise];
52
 		}
53
 		}
53
 	}
54
 	}
55
+	
56
+	return nil;
54
 }
57
 }
55
 
58
 
56
 @end
59
 @end

+ 2
- 2
lib/ios/RNNNavigationOptions.h View File

6
 #import "RNNTopTabOptions.h"
6
 #import "RNNTopTabOptions.h"
7
 #import "RNNTopTabsOptions.h"
7
 #import "RNNTopTabsOptions.h"
8
 #import "RNNOverlayOptions.h"
8
 #import "RNNOverlayOptions.h"
9
-#import "RNNTransitionOptions.h"
9
+#import "RNNAnimationOptions.h"
10
 
10
 
11
 extern const NSInteger BLUR_STATUS_TAG;
11
 extern const NSInteger BLUR_STATUS_TAG;
12
 extern const NSInteger BLUR_TOPBAR_TAG;
12
 extern const NSInteger BLUR_TOPBAR_TAG;
21
 @property (nonatomic, strong) RNNTopTabOptions* topTab;
21
 @property (nonatomic, strong) RNNTopTabOptions* topTab;
22
 @property (nonatomic, strong) RNNSideMenuOptions* sideMenu;
22
 @property (nonatomic, strong) RNNSideMenuOptions* sideMenu;
23
 @property (nonatomic, strong) RNNOverlayOptions* overlay;
23
 @property (nonatomic, strong) RNNOverlayOptions* overlay;
24
-@property (nonatomic, strong) RNNTransitionOptions* customTransition;
24
+@property (nonatomic, strong) RNNAnimationOptions* customTransition;
25
 
25
 
26
 @property (nonatomic, strong) RNNNavigationOptions* defaultOptions;
26
 @property (nonatomic, strong) RNNNavigationOptions* defaultOptions;
27
 
27
 

+ 1
- 1
lib/ios/RNNNavigationOptions.m View File

32
 	self.bottomTab = [[RNNBottomTabOptions alloc] initWithDict:[options objectForKey:@"bottomTab"]];
32
 	self.bottomTab = [[RNNBottomTabOptions alloc] initWithDict:[options objectForKey:@"bottomTab"]];
33
 	self.overlay = [[RNNOverlayOptions alloc] initWithDict:[options objectForKey:@"overlay"]];
33
 	self.overlay = [[RNNOverlayOptions alloc] initWithDict:[options objectForKey:@"overlay"]];
34
 	self.animated = [options objectForKey:@"animated"];
34
 	self.animated = [options objectForKey:@"animated"];
35
-	self.customTransition = [[RNNTransitionOptions alloc] initWithDict:[options objectForKey:@"customTransition"]];
35
+	self.customTransition = [[RNNAnimationOptions alloc] initWithDict:[options objectForKey:@"customTransition"]];
36
 	
36
 	
37
 	return self;
37
 	return self;
38
 }
38
 }

+ 1
- 1
lib/ios/RNNNavigationStackManager.h View File

11
 
11
 
12
 
12
 
13
 -(void)push:(UIViewController<RNNRootViewProtocol>*)newTop onTop:(NSString*)componentId completion:(RNNTransitionCompletionBlock)completion;
13
 -(void)push:(UIViewController<RNNRootViewProtocol>*)newTop onTop:(NSString*)componentId completion:(RNNTransitionCompletionBlock)completion;
14
--(void)pop:(NSString*)componentId withTransitionOptions:(RNNTransitionOptions*)transitionOptions;
14
+-(void)pop:(NSString*)componentId withTransitionOptions:(RNNAnimationOptions*)transitionOptions;
15
 -(void)popTo:(NSString*)componentId;
15
 -(void)popTo:(NSString*)componentId;
16
 -(void)popToRoot:(NSString*)componentId;
16
 -(void)popToRoot:(NSString*)componentId;
17
 
17
 

+ 1
- 1
lib/ios/RNNNavigationStackManager.m View File

60
 	self.fromVC = nil;
60
 	self.fromVC = nil;
61
 }
61
 }
62
 
62
 
63
--(void)pop:(NSString *)componentId withTransitionOptions:(RNNTransitionOptions *)transitionOptions {
63
+-(void)pop:(NSString *)componentId withTransitionOptions:(RNNAnimationOptions *)transitionOptions {
64
 	UIViewController<RNNRootViewProtocol>* vc = (UIViewController<RNNRootViewProtocol>*)[_store findComponentForId:componentId];
64
 	UIViewController<RNNRootViewProtocol>* vc = (UIViewController<RNNRootViewProtocol>*)[_store findComponentForId:componentId];
65
 	UINavigationController* nvc = [vc navigationController];
65
 	UINavigationController* nvc = [vc navigationController];
66
 	if ([nvc topViewController] == vc) {
66
 	if ([nvc topViewController] == vc) {

+ 16
- 0
lib/ios/RNNTransition.h View File

1
+#import <Foundation/Foundation.h>
2
+#import "RNNTransitionStateHolder.h"
3
+#import "RNNAnimatedView.h"
4
+
5
+@interface RNNTransition : NSObject
6
+
7
+@property (nonatomic, strong) RNNAnimatedView* animatedView;
8
+@property (nonatomic, strong) RNNTransitionStateHolder* options;
9
+
10
+- (instancetype)initFromVC:(UIViewController*)fromVC toVC:(UIViewController*)toVC transitionOptions:(RNNTransitionStateHolder*)transitionOptions isBackButton:(BOOL)isBackButton;
11
+
12
+- (void)setAnimatedViewFinalProperties;
13
+
14
+- (void)transitionCompleted;
15
+
16
+@end

+ 86
- 0
lib/ios/RNNTransition.m View File

1
+#import "RNNTransition.h"
2
+#import "RNNElementFinder.h"
3
+#import "RNNTransitionStateHolder.h"
4
+#import "RNNViewLocation.h"
5
+#import "RNNInteractivePopAnimator.h"
6
+
7
+@interface RNNTransition () {
8
+	UIViewController* _toVC;
9
+	UIViewController* _fromVC;
10
+	BOOL _isBackButton;
11
+}
12
+
13
+@property (nonatomic, strong) RNNElementView* fromElement;
14
+@property (nonatomic, strong) RNNElementView* toElement;
15
+@property (nonatomic, strong) RNNViewLocation* locations;
16
+
17
+@end
18
+
19
+@implementation RNNTransition
20
+
21
+- (instancetype)initFromVC:(UIViewController *)fromVC toVC:(UIViewController *)toVC transitionOptions:(RNNTransitionStateHolder *)transitionOptions isBackButton:(BOOL)isBackButton {
22
+	self = [super init];
23
+	
24
+	_toVC = toVC;
25
+	_fromVC = fromVC;
26
+	_isBackButton = isBackButton;
27
+	
28
+	self.options = transitionOptions;
29
+	
30
+	RNNElementFinder* elementFinder = [[RNNElementFinder alloc] initWithToVC:toVC andfromVC:fromVC];
31
+	self.fromElement = [elementFinder findElementForId:self.options.fromId];
32
+	self.toElement = [elementFinder findElementForId:transitionOptions.toId];
33
+	self.locations = [[RNNViewLocation alloc] initWithFromElement:self.fromElement toElement:self.toElement startPoint:CGPointMake(self.options.startX, self.options.startY) endPoint:CGPointMake(self.options.endX, self.options.endY) andVC:fromVC];
34
+	
35
+	self.animatedView = [[RNNAnimatedView alloc] initFromElement:self.fromElement toElement:self.toElement andLocation:self.locations andIsBackButton:isBackButton startAlpha:self.options.startAlpha endAlpha:self.options.endAlpha];
36
+	
37
+	if (transitionOptions.isSharedElementTransition) {
38
+		[self.toElement setHidden: YES];
39
+	}
40
+	
41
+	[self.fromElement setHidden:YES];
42
+	
43
+	return self;
44
+}
45
+
46
+- (void)setAnimatedViewFinalProperties {
47
+	CGFloat alpha = _isBackButton ? self.options.startAlpha : self.options.endAlpha;
48
+	self.animatedView.alpha = alpha;
49
+	
50
+	CGPoint center = _isBackButton ? self.locations.fromCenter : self.locations.toCenter;
51
+	self.animatedView.center = center;
52
+	
53
+	CGAffineTransform transform = _isBackButton ? self.locations.transformBack : self.locations.transform;
54
+	self.animatedView.transform = transform;
55
+	
56
+	RNNElementView* fromElement = _isBackButton ? self.toElement : self.fromElement;
57
+	RNNElementView* toElement = _isBackButton ? self.fromElement : self.toElement;
58
+	
59
+	if (self.options.isSharedElementTransition) {
60
+		if ([[fromElement subviews][0] isKindOfClass:[UIImageView class]]) {
61
+			self.animatedView.contentMode = UIViewContentModeScaleAspectFill;
62
+			if ([toElement resizeMode]){
63
+				self.animatedView.contentMode = [RNNAnimatedView contentModefromString:[toElement resizeMode]];
64
+			}
65
+		}
66
+	}
67
+}
68
+
69
+
70
+- (void)transitionCompleted {
71
+	[self.fromElement setHidden:NO];
72
+	if (self.options.isSharedElementTransition) {
73
+		[self.toElement setHidden:NO];
74
+	}
75
+	
76
+	[self.animatedView removeFromSuperview];
77
+	
78
+	if (self.options.interactivePop) {
79
+		RNNInteractivePopAnimator* interactivePopAnimator = [[RNNInteractivePopAnimator alloc] initWithTopView:self.toElement andBottomView:self.fromElement andOriginFrame:self.locations.fromFrame andViewController:_toVC];
80
+		UIPanGestureRecognizer* gesture = [[UIPanGestureRecognizer alloc] initWithTarget:interactivePopAnimator
81
+																				  action:@selector(handleGesture:)];
82
+		[self.toElement addGestureRecognizer:gesture];
83
+	}
84
+}
85
+
86
+@end

+ 2
- 12
lib/ios/RNNTransitionStateHolder.h View File

1
 #import <Foundation/Foundation.h>
1
 #import <Foundation/Foundation.h>
2
-#import "RNNElementView.h"
3
-#import "RNNViewLocation.h"
4
-#import "RNNAnimatedView.h"
5
 
2
 
6
-@class RNNAnimatedView;
7
-@class RNNViewLocation;
8
 @interface RNNTransitionStateHolder : NSObject
3
 @interface RNNTransitionStateHolder : NSObject
9
 
4
 
10
 @property (nonatomic) double startAlpha;
5
 @property (nonatomic) double startAlpha;
14
 @property (nonatomic) double springVelocity;
9
 @property (nonatomic) double springVelocity;
15
 @property (nonatomic) double springDamping;
10
 @property (nonatomic) double springDamping;
16
 @property (nonatomic) double startDelay;
11
 @property (nonatomic) double startDelay;
17
-@property (nonatomic, strong) RNNElementView* fromElement;
18
 @property (nonatomic, strong) NSString* fromElementType;
12
 @property (nonatomic, strong) NSString* fromElementType;
19
-@property (nonatomic) UIViewContentMode fromElementResizeMode;
20
-@property (nonatomic, strong) RNNElementView* toElement;
21
 @property (nonatomic, strong) NSString* fromId;
13
 @property (nonatomic, strong) NSString* fromId;
22
 @property (nonatomic, strong) NSString* toId;
14
 @property (nonatomic, strong) NSString* toId;
23
-@property (nonatomic, strong) RNNAnimatedView* animatedView;
24
 @property (nonatomic) BOOL isSharedElementTransition;
15
 @property (nonatomic) BOOL isSharedElementTransition;
25
-@property (nonatomic, strong) RNNViewLocation* locations;
26
-@property (nonatomic) BOOL isFromVC;
27
 @property (nonatomic) double startY;
16
 @property (nonatomic) double startY;
28
 @property (nonatomic) double endY;
17
 @property (nonatomic) double endY;
29
 @property (nonatomic) double startX;
18
 @property (nonatomic) double startX;
30
 @property (nonatomic) double endX;
19
 @property (nonatomic) double endX;
31
 
20
 
32
--(instancetype)initWithTransition:(NSDictionary*)transition;
21
+- (instancetype)initWithTransition:(NSDictionary*)transition;
22
+
33
 @end
23
 @end

+ 0
- 6
lib/ios/RNNTransitionStateHolder.m View File

1
 #import "RNNTransitionStateHolder.h"
1
 #import "RNNTransitionStateHolder.h"
2
 #import "RNNUtils.h"
2
 #import "RNNUtils.h"
3
-#import "RNNElementFinder.h"
4
 
3
 
5
 @implementation RNNTransitionStateHolder
4
 @implementation RNNTransitionStateHolder
6
 
5
 
19
 	self.endY = [RNNUtils getDoubleOrKey:transition[@"y"] withKey:@"to" withDefault:0];
18
 	self.endY = [RNNUtils getDoubleOrKey:transition[@"y"] withKey:@"to" withDefault:0];
20
 	self.fromId = [transition objectForKey:@"fromId"];
19
 	self.fromId = [transition objectForKey:@"fromId"];
21
 	self.toId = [transition objectForKey:@"toId"];
20
 	self.toId = [transition objectForKey:@"toId"];
22
-	self.fromElement = nil;
23
 	self.fromElementType = nil;
21
 	self.fromElementType = nil;
24
-	self.fromElementResizeMode = UIViewContentModeScaleAspectFill;
25
-	self.toElement = nil;
26
-	self.animatedView = nil;
27
-	self.locations  = nil; 
28
 	self.isSharedElementTransition = [[transition objectForKey:@"type"] isEqualToString:@"sharedElement"];
22
 	self.isSharedElementTransition = [[transition objectForKey:@"type"] isEqualToString:@"sharedElement"];
29
 	return self;
23
 	return self;
30
 }
24
 }

+ 6
- 12
lib/ios/RNNViewLocation.h View File

1
-//
2
-//  RNNViewLocation.h
3
-//  ReactNativeNavigation
4
-//
5
-//  Created by Elad Bogomolny on 03/10/2017.
6
-//  Copyright © 2017 Wix. All rights reserved.
7
-//
8
-
9
 #import <Foundation/Foundation.h>
1
 #import <Foundation/Foundation.h>
10
-#import <UIKit/UIKit.h>
11
-#import "RNNTransitionStateHolder.h"
2
+#import "RNNElementView.h"
12
 
3
 
13
-@class RNNTransitionStateHolder;
14
 @interface RNNViewLocation : NSObject
4
 @interface RNNViewLocation : NSObject
5
+
15
 @property (nonatomic) CGRect fromFrame;
6
 @property (nonatomic) CGRect fromFrame;
16
 @property (nonatomic) CGPoint fromCenter;
7
 @property (nonatomic) CGPoint fromCenter;
17
 @property (nonatomic) CGSize fromSize;
8
 @property (nonatomic) CGSize fromSize;
21
 @property (nonatomic) CGAffineTransform transform;
12
 @property (nonatomic) CGAffineTransform transform;
22
 @property (nonatomic) CGAffineTransform transformBack;
13
 @property (nonatomic) CGAffineTransform transformBack;
23
 
14
 
24
--(instancetype)initWithTransition:(RNNTransitionStateHolder*)transition andVC:(UIViewController*)vc;
15
+-(instancetype)initWithFromElement:(RNNElementView*)fromElement toElement:(RNNElementView*)toElement startPoint:(CGPoint)startPoint endPoint:(CGPoint)endPoint andVC:(UIViewController*)vc;
16
+
25
 -(CGRect)frameFromSuperViewController:(UIView*)view andVC:(UIViewController*)vc;
17
 -(CGRect)frameFromSuperViewController:(UIView*)view andVC:(UIViewController*)vc;
18
+
26
 -(CGPoint)centerFromSuperViewController:(UIView*)view andVC:(UIViewController*)vc;
19
 -(CGPoint)centerFromSuperViewController:(UIView*)view andVC:(UIViewController*)vc;
20
+
27
 @end
21
 @end

+ 18
- 14
lib/ios/RNNViewLocation.m View File

1
 #import "RNNViewLocation.h"
1
 #import "RNNViewLocation.h"
2
 
2
 
3
 @implementation RNNViewLocation
3
 @implementation RNNViewLocation
4
--(instancetype)initWithTransition:(RNNTransitionStateHolder*)transition andVC:(UIViewController*)vc {
4
+
5
+- (instancetype)initWithFromElement:(RNNElementView *)fromElement toElement:(RNNElementView *)toElement startPoint:(CGPoint)startPoint endPoint:(CGPoint)endPoint andVC:(UIViewController *)vc {
5
 	self = [super init];
6
 	self = [super init];
6
-	self.fromFrame = [self frameFromSuperViewController:[transition.fromElement subviews][0] andVC:vc];
7
+	
8
+	self.fromFrame = [self frameFromSuperViewController:[fromElement subviews][0] andVC:vc];
7
 	CGSize fromSize = self.fromFrame.size;
9
 	CGSize fromSize = self.fromFrame.size;
8
-	CGPoint fromCenter = [self centerFromSuperViewController:[transition.fromElement subviews][0] andVC:vc];
9
-	fromCenter.x = fromCenter.x + transition.startX;
10
-	fromCenter.y = fromCenter.y + transition.startY;
10
+	CGPoint fromCenter = [self centerFromSuperViewController:[fromElement subviews][0] andVC:vc];
11
+	fromCenter.x = fromCenter.x + startPoint.x;
12
+	fromCenter.y = fromCenter.y + startPoint.y;
11
 	self.fromCenter = fromCenter;
13
 	self.fromCenter = fromCenter;
12
-	CGRect toFrame = [self frameFromSuperViewController:[transition.fromElement subviews][0] andVC:vc];
14
+	CGRect toFrame = [self frameFromSuperViewController:[fromElement subviews][0] andVC:vc];
13
 	CGSize toSize = self.fromFrame.size;
15
 	CGSize toSize = self.fromFrame.size;
14
-	CGPoint toCenter = [self centerFromSuperViewController:[transition.fromElement subviews][0] andVC:vc];
15
-	if (transition.toElement) {
16
-	   toFrame = [self frameFromSuperViewController:[transition.toElement subviews][0] andVC:vc];
16
+	CGPoint toCenter = [self centerFromSuperViewController:[fromElement subviews][0] andVC:vc];
17
+	if (toElement) {
18
+	   toFrame = [self frameFromSuperViewController:[toElement subviews][0] andVC:vc];
17
 		toSize = toFrame.size;
19
 		toSize = toFrame.size;
18
-		toCenter = [self centerFromSuperViewController:[transition.toElement subviews][0] andVC:vc];
20
+		toCenter = [self centerFromSuperViewController:[toElement subviews][0] andVC:vc];
19
 	}
21
 	}
20
-	toCenter.x = toCenter.x + transition.endX;
21
-	toCenter.y = toCenter.y + transition.endY;
22
+	toCenter.x = toCenter.x + endPoint.x;
23
+	toCenter.y = toCenter.y + endPoint.y;
22
 	
24
 	
23
 	CGAffineTransform transform = CGAffineTransformMakeScale(toSize.width/fromSize.width ,toSize.height/fromSize.height);
25
 	CGAffineTransform transform = CGAffineTransformMakeScale(toSize.width/fromSize.width ,toSize.height/fromSize.height);
24
 	CGAffineTransform transformBack = CGAffineTransformMakeScale(fromSize.width/toSize.width ,fromSize.height/toSize.height);
26
 	CGAffineTransform transformBack = CGAffineTransformMakeScale(fromSize.width/toSize.width ,fromSize.height/toSize.height);
27
+	
25
 	self.toFrame = toFrame;
28
 	self.toFrame = toFrame;
26
 	self.fromSize = fromSize;
29
 	self.fromSize = fromSize;
27
 	self.toSize = toSize;
30
 	self.toSize = toSize;
28
 	self.toCenter = toCenter;
31
 	self.toCenter = toCenter;
29
 	self.transform = transform;
32
 	self.transform = transform;
30
 	self.transformBack = transformBack;
33
 	self.transformBack = transformBack;
34
+	
31
 	return self;
35
 	return self;
32
 }
36
 }
33
 
37
 
34
--(CGRect)frameFromSuperViewController:(UIView*)view andVC:(UIViewController*)vc{
38
+- (CGRect)frameFromSuperViewController:(UIView *)view andVC:(UIViewController *)vc{
35
 	CGPoint sharedViewFrameOrigin = [view.superview convertPoint:view.frame.origin toView:vc.view];
39
 	CGPoint sharedViewFrameOrigin = [view.superview convertPoint:view.frame.origin toView:vc.view];
36
 	CGRect originRect = CGRectMake(sharedViewFrameOrigin.x, sharedViewFrameOrigin.y, view.frame.size.width, view.frame.size.height);
40
 	CGRect originRect = CGRectMake(sharedViewFrameOrigin.x, sharedViewFrameOrigin.y, view.frame.size.width, view.frame.size.height);
37
 	return originRect;
41
 	return originRect;
38
 }
42
 }
39
 
43
 
40
--(CGPoint)centerFromSuperViewController:(UIView*)view andVC:(UIViewController*)vc{
44
+- (CGPoint)centerFromSuperViewController:(UIView *)view andVC:(UIViewController *)vc{
41
 	CGPoint sharedViewFrameOrigin = [view.superview convertPoint:view.frame.origin toView:vc.view];
45
 	CGPoint sharedViewFrameOrigin = [view.superview convertPoint:view.frame.origin toView:vc.view];
42
 	CGRect originRect = CGRectMake(sharedViewFrameOrigin.x, sharedViewFrameOrigin.y, view.frame.size.width, view.frame.size.height);
46
 	CGRect originRect = CGRectMake(sharedViewFrameOrigin.x, sharedViewFrameOrigin.y, view.frame.size.width, view.frame.size.height);
43
 	CGFloat x = originRect.origin.x + view.frame.size.width/2;
47
 	CGFloat x = originRect.origin.x + view.frame.size.width/2;

+ 16
- 8
lib/ios/ReactNativeNavigation.xcodeproj/project.pbxproj View File

67
 		5032774F2015E86D00ECD75D /* RNNNavigationEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = 5032774D2015E86D00ECD75D /* RNNNavigationEvent.m */; };
67
 		5032774F2015E86D00ECD75D /* RNNNavigationEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = 5032774D2015E86D00ECD75D /* RNNNavigationEvent.m */; };
68
 		503277602016302900ECD75D /* RNNComponentLifecycleEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 5032775E2016302900ECD75D /* RNNComponentLifecycleEvent.h */; };
68
 		503277602016302900ECD75D /* RNNComponentLifecycleEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 5032775E2016302900ECD75D /* RNNComponentLifecycleEvent.h */; };
69
 		503277612016302900ECD75D /* RNNComponentLifecycleEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = 5032775F2016302900ECD75D /* RNNComponentLifecycleEvent.m */; };
69
 		503277612016302900ECD75D /* RNNComponentLifecycleEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = 5032775F2016302900ECD75D /* RNNComponentLifecycleEvent.m */; };
70
+		50451D0D2042F70900695F00 /* RNNTransition.h in Headers */ = {isa = PBXBuildFile; fileRef = 50451D0B2042F70900695F00 /* RNNTransition.h */; };
71
+		50451D0E2042F70900695F00 /* RNNTransition.m in Sources */ = {isa = PBXBuildFile; fileRef = 50451D0C2042F70900695F00 /* RNNTransition.m */; };
70
 		504AFE641FFE53070076E904 /* RNNOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 504AFE621FFE53070076E904 /* RNNOptions.h */; };
72
 		504AFE641FFE53070076E904 /* RNNOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 504AFE621FFE53070076E904 /* RNNOptions.h */; };
71
 		504AFE651FFE53070076E904 /* RNNOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 504AFE631FFE53070076E904 /* RNNOptions.m */; };
73
 		504AFE651FFE53070076E904 /* RNNOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 504AFE631FFE53070076E904 /* RNNOptions.m */; };
72
 		504AFE741FFFF0540076E904 /* RNNTopTabsOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 504AFE721FFFF0540076E904 /* RNNTopTabsOptions.h */; };
74
 		504AFE741FFFF0540076E904 /* RNNTopTabsOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 504AFE721FFFF0540076E904 /* RNNTopTabsOptions.h */; };
73
 		504AFE751FFFF0540076E904 /* RNNTopTabsOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 504AFE731FFFF0540076E904 /* RNNTopTabsOptions.m */; };
75
 		504AFE751FFFF0540076E904 /* RNNTopTabsOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 504AFE731FFFF0540076E904 /* RNNTopTabsOptions.m */; };
74
 		504AFE761FFFF1E00076E904 /* RNNNavigationOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = E83BAD691F27362500A9F3DD /* RNNNavigationOptions.h */; };
76
 		504AFE761FFFF1E00076E904 /* RNNNavigationOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = E83BAD691F27362500A9F3DD /* RNNNavigationOptions.h */; };
75
 		504AFE771FFFF1E20076E904 /* RNNTopBarOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = A7626BFE1FC2FB6700492FB8 /* RNNTopBarOptions.h */; };
77
 		504AFE771FFFF1E20076E904 /* RNNTopBarOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = A7626BFE1FC2FB6700492FB8 /* RNNTopBarOptions.h */; };
76
-		507E7D57201DDD3000444E6C /* RNNTransitionOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 507E7D55201DDD3000444E6C /* RNNTransitionOptions.h */; };
77
-		507E7D58201DDD3000444E6C /* RNNTransitionOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 507E7D56201DDD3000444E6C /* RNNTransitionOptions.m */; };
78
+		507E7D57201DDD3000444E6C /* RNNAnimationOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 507E7D55201DDD3000444E6C /* RNNAnimationOptions.h */; };
79
+		507E7D58201DDD3000444E6C /* RNNAnimationOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 507E7D56201DDD3000444E6C /* RNNAnimationOptions.m */; };
78
 		507F43C51FF4F17C00D9425B /* RNNTopTabsViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 507F43C31FF4F17C00D9425B /* RNNTopTabsViewController.h */; };
80
 		507F43C51FF4F17C00D9425B /* RNNTopTabsViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 507F43C31FF4F17C00D9425B /* RNNTopTabsViewController.h */; };
79
 		507F43C61FF4F17C00D9425B /* RNNTopTabsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 507F43C41FF4F17C00D9425B /* RNNTopTabsViewController.m */; };
81
 		507F43C61FF4F17C00D9425B /* RNNTopTabsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 507F43C41FF4F17C00D9425B /* RNNTopTabsViewController.m */; };
80
 		507F43C91FF4F9CC00D9425B /* RNNTopTabOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 507F43C71FF4F9CC00D9425B /* RNNTopTabOptions.h */; };
82
 		507F43C91FF4F9CC00D9425B /* RNNTopTabOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 507F43C71FF4F9CC00D9425B /* RNNTopTabOptions.h */; };
246
 		5032774D2015E86D00ECD75D /* RNNNavigationEvent.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNNavigationEvent.m; sourceTree = "<group>"; };
248
 		5032774D2015E86D00ECD75D /* RNNNavigationEvent.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNNavigationEvent.m; sourceTree = "<group>"; };
247
 		5032775E2016302900ECD75D /* RNNComponentLifecycleEvent.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNComponentLifecycleEvent.h; sourceTree = "<group>"; };
249
 		5032775E2016302900ECD75D /* RNNComponentLifecycleEvent.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNComponentLifecycleEvent.h; sourceTree = "<group>"; };
248
 		5032775F2016302900ECD75D /* RNNComponentLifecycleEvent.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNComponentLifecycleEvent.m; sourceTree = "<group>"; };
250
 		5032775F2016302900ECD75D /* RNNComponentLifecycleEvent.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNComponentLifecycleEvent.m; sourceTree = "<group>"; };
251
+		50451D0B2042F70900695F00 /* RNNTransition.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNTransition.h; sourceTree = "<group>"; };
252
+		50451D0C2042F70900695F00 /* RNNTransition.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNTransition.m; sourceTree = "<group>"; };
249
 		504AFE621FFE53070076E904 /* RNNOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNOptions.h; sourceTree = "<group>"; };
253
 		504AFE621FFE53070076E904 /* RNNOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNOptions.h; sourceTree = "<group>"; };
250
 		504AFE631FFE53070076E904 /* RNNOptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNOptions.m; sourceTree = "<group>"; };
254
 		504AFE631FFE53070076E904 /* RNNOptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNOptions.m; sourceTree = "<group>"; };
251
 		504AFE721FFFF0540076E904 /* RNNTopTabsOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNTopTabsOptions.h; sourceTree = "<group>"; };
255
 		504AFE721FFFF0540076E904 /* RNNTopTabsOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNTopTabsOptions.h; sourceTree = "<group>"; };
252
 		504AFE731FFFF0540076E904 /* RNNTopTabsOptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNTopTabsOptions.m; sourceTree = "<group>"; };
256
 		504AFE731FFFF0540076E904 /* RNNTopTabsOptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNTopTabsOptions.m; sourceTree = "<group>"; };
253
-		507E7D55201DDD3000444E6C /* RNNTransitionOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNTransitionOptions.h; sourceTree = "<group>"; };
254
-		507E7D56201DDD3000444E6C /* RNNTransitionOptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNTransitionOptions.m; sourceTree = "<group>"; };
257
+		507E7D55201DDD3000444E6C /* RNNAnimationOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNAnimationOptions.h; sourceTree = "<group>"; };
258
+		507E7D56201DDD3000444E6C /* RNNAnimationOptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNAnimationOptions.m; sourceTree = "<group>"; };
255
 		507F43C31FF4F17C00D9425B /* RNNTopTabsViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNTopTabsViewController.h; sourceTree = "<group>"; };
259
 		507F43C31FF4F17C00D9425B /* RNNTopTabsViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNTopTabsViewController.h; sourceTree = "<group>"; };
256
 		507F43C41FF4F17C00D9425B /* RNNTopTabsViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNTopTabsViewController.m; sourceTree = "<group>"; };
260
 		507F43C41FF4F17C00D9425B /* RNNTopTabsViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNTopTabsViewController.m; sourceTree = "<group>"; };
257
 		507F43C71FF4F9CC00D9425B /* RNNTopTabOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNTopTabOptions.h; sourceTree = "<group>"; };
261
 		507F43C71FF4F9CC00D9425B /* RNNTopTabOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNTopTabOptions.h; sourceTree = "<group>"; };
477
 				50CB3B681FDE911400AA153B /* RNNSideMenuOptions.m */,
481
 				50CB3B681FDE911400AA153B /* RNNSideMenuOptions.m */,
478
 				50A00C35200F84D6000F01A6 /* RNNOverlayOptions.h */,
482
 				50A00C35200F84D6000F01A6 /* RNNOverlayOptions.h */,
479
 				50A00C36200F84D6000F01A6 /* RNNOverlayOptions.m */,
483
 				50A00C36200F84D6000F01A6 /* RNNOverlayOptions.m */,
480
-				507E7D55201DDD3000444E6C /* RNNTransitionOptions.h */,
481
-				507E7D56201DDD3000444E6C /* RNNTransitionOptions.m */,
484
+				507E7D55201DDD3000444E6C /* RNNAnimationOptions.h */,
485
+				507E7D56201DDD3000444E6C /* RNNAnimationOptions.m */,
482
 			);
486
 			);
483
 			name = Options;
487
 			name = Options;
484
 			sourceTree = "<group>";
488
 			sourceTree = "<group>";
650
 				E8AEDB491F5C0BAF000F5A6A /* RNNInteractivePopAnimator.m */,
654
 				E8AEDB491F5C0BAF000F5A6A /* RNNInteractivePopAnimator.m */,
651
 				E8E5182C1F83A48B000467AC /* RNNTransitionStateHolder.h */,
655
 				E8E5182C1F83A48B000467AC /* RNNTransitionStateHolder.h */,
652
 				E8E5182D1F83A48B000467AC /* RNNTransitionStateHolder.m */,
656
 				E8E5182D1F83A48B000467AC /* RNNTransitionStateHolder.m */,
657
+				50451D0B2042F70900695F00 /* RNNTransition.h */,
658
+				50451D0C2042F70900695F00 /* RNNTransition.m */,
653
 				E8E518341F83B94A000467AC /* RNNViewLocation.h */,
659
 				E8E518341F83B94A000467AC /* RNNViewLocation.h */,
654
 				E8E518351F83B94A000467AC /* RNNViewLocation.m */,
660
 				E8E518351F83B94A000467AC /* RNNViewLocation.m */,
655
 				E8DA243E1F97459B00CD552B /* RNNElementFinder.h */,
661
 				E8DA243E1F97459B00CD552B /* RNNElementFinder.h */,
736
 				E8A5CD621F49114F00E89D0D /* RNNElement.h in Headers */,
742
 				E8A5CD621F49114F00E89D0D /* RNNElement.h in Headers */,
737
 				504AFE741FFFF0540076E904 /* RNNTopTabsOptions.h in Headers */,
743
 				504AFE741FFFF0540076E904 /* RNNTopTabsOptions.h in Headers */,
738
 				E8E5182E1F83A48B000467AC /* RNNTransitionStateHolder.h in Headers */,
744
 				E8E5182E1F83A48B000467AC /* RNNTransitionStateHolder.h in Headers */,
739
-				507E7D57201DDD3000444E6C /* RNNTransitionOptions.h in Headers */,
745
+				507E7D57201DDD3000444E6C /* RNNAnimationOptions.h in Headers */,
740
 				2DCD9195200014A900EDC75D /* RNNBridgeManager.h in Headers */,
746
 				2DCD9195200014A900EDC75D /* RNNBridgeManager.h in Headers */,
741
 				7B1126A91E2D2B6C00F9B03B /* RNNControllerFactory.h in Headers */,
747
 				7B1126A91E2D2B6C00F9B03B /* RNNControllerFactory.h in Headers */,
742
 				263905D61E4C94970023D7D3 /* RNNSideMenuController.h in Headers */,
748
 				263905D61E4C94970023D7D3 /* RNNSideMenuController.h in Headers */,
744
 				7BEF0D1C1E43771B003E96B0 /* RNNLayoutNode.h in Headers */,
750
 				7BEF0D1C1E43771B003E96B0 /* RNNLayoutNode.h in Headers */,
745
 				507F43C91FF4F9CC00D9425B /* RNNTopTabOptions.h in Headers */,
751
 				507F43C91FF4F9CC00D9425B /* RNNTopTabOptions.h in Headers */,
746
 				E8A5CD521F464F0400E89D0D /* RNNAnimator.h in Headers */,
752
 				E8A5CD521F464F0400E89D0D /* RNNAnimator.h in Headers */,
753
+				50451D0D2042F70900695F00 /* RNNTransition.h in Headers */,
747
 				507F43F81FF525B500D9425B /* RNNSegmentedControl.h in Headers */,
754
 				507F43F81FF525B500D9425B /* RNNSegmentedControl.h in Headers */,
748
 			);
755
 			);
749
 			runOnlyForDeploymentPostprocessing = 0;
756
 			runOnlyForDeploymentPostprocessing = 0;
858
 				263905C71E4C6F440023D7D3 /* SidebarFeedlyAnimation.m in Sources */,
865
 				263905C71E4C6F440023D7D3 /* SidebarFeedlyAnimation.m in Sources */,
859
 				263905B41E4C6F440023D7D3 /* MMDrawerVisualState.m in Sources */,
866
 				263905B41E4C6F440023D7D3 /* MMDrawerVisualState.m in Sources */,
860
 				263905C51E4C6F440023D7D3 /* SidebarFacebookAnimation.m in Sources */,
867
 				263905C51E4C6F440023D7D3 /* SidebarFacebookAnimation.m in Sources */,
868
+				50451D0E2042F70900695F00 /* RNNTransition.m in Sources */,
861
 				7BEF0D191E437684003E96B0 /* RNNRootViewController.m in Sources */,
869
 				7BEF0D191E437684003E96B0 /* RNNRootViewController.m in Sources */,
862
 				263905C31E4C6F440023D7D3 /* SidebarAnimation.m in Sources */,
870
 				263905C31E4C6F440023D7D3 /* SidebarAnimation.m in Sources */,
863
 				E8A5CD531F464F0400E89D0D /* RNNAnimator.m in Sources */,
871
 				E8A5CD531F464F0400E89D0D /* RNNAnimator.m in Sources */,
885
 				263905BA1E4C6F440023D7D3 /* RCCDrawerController.m in Sources */,
893
 				263905BA1E4C6F440023D7D3 /* RCCDrawerController.m in Sources */,
886
 				50F5DFC21F407A8C001A00BC /* RNNTabBarController.m in Sources */,
894
 				50F5DFC21F407A8C001A00BC /* RNNTabBarController.m in Sources */,
887
 				263905BC1E4C6F440023D7D3 /* RCCDrawerHelper.m in Sources */,
895
 				263905BC1E4C6F440023D7D3 /* RCCDrawerHelper.m in Sources */,
888
-				507E7D58201DDD3000444E6C /* RNNTransitionOptions.m in Sources */,
896
+				507E7D58201DDD3000444E6C /* RNNAnimationOptions.m in Sources */,
889
 				2145452A1F4DC85F006E8DA1 /* RCTHelpers.m in Sources */,
897
 				2145452A1F4DC85F006E8DA1 /* RCTHelpers.m in Sources */,
890
 				2DCD9196200014A900EDC75D /* RNNBridgeManager.m in Sources */,
898
 				2DCD9196200014A900EDC75D /* RNNBridgeManager.m in Sources */,
891
 				263905C11E4C6F440023D7D3 /* SidebarAirbnbAnimation.m in Sources */,
899
 				263905C11E4C6F440023D7D3 /* SidebarAirbnbAnimation.m in Sources */,