Преглед на файлове

Fix and refactor animations options (#4880)

Yogev Ben David преди 5 години
родител
ревизия
a98f18704c
No account linked to committer's email address

+ 12
- 0
lib/ios/RNNAnimationConfigurationOptions.h Целия файл

@@ -0,0 +1,12 @@
1
+#import "RNNOptions.h"
2
+
3
+@interface RNNAnimationConfigurationOptions : RNNOptions
4
+
5
+@property (nonatomic, strong) Double* from;
6
+@property (nonatomic, strong) Double* to;
7
+@property (nonatomic, strong) Double* duration;
8
+@property (nonatomic, strong) Double* startDelay;
9
+
10
+- (BOOL)hasAnimation;
11
+
12
+@end

+ 20
- 0
lib/ios/RNNAnimationConfigurationOptions.m Целия файл

@@ -0,0 +1,20 @@
1
+#import "RNNAnimationConfigurationOptions.h"
2
+
3
+@implementation RNNAnimationConfigurationOptions
4
+
5
+- (instancetype)initWithDict:(NSDictionary *)dict {
6
+	self = [super init];
7
+	
8
+	self.from = [DoubleParser parse:dict key:@"from"];
9
+	self.to = [DoubleParser parse:dict key:@"to"];
10
+	self.startDelay = [DoubleParser parse:dict key:@"startDelay"];
11
+	self.duration = [DoubleParser parse:dict key:@"duration"];
12
+	
13
+	return self;
14
+}
15
+
16
+- (BOOL)hasAnimation {
17
+	return self.from.hasValue && self.to.hasValue;
18
+}
19
+
20
+@end

lib/ios/RNNTransitionsOptions.h → lib/ios/RNNAnimationsOptions.h Целия файл

@@ -1,8 +1,7 @@
1 1
 #import "RNNOptions.h"
2
-#import "RNNTransitionStateHolder.h"
3 2
 #import "RNNScreenTransition.h"
4 3
 
5
-@interface RNNTransitionsOptions : RNNOptions
4
+@interface RNNAnimationsOptions : RNNOptions
6 5
 
7 6
 @property (nonatomic, strong) RNNScreenTransition* push;
8 7
 @property (nonatomic, strong) RNNScreenTransition* pop;

+ 18
- 0
lib/ios/RNNAnimationsOptions.m Целия файл

@@ -0,0 +1,18 @@
1
+#import "RNNAnimationsOptions.h"
2
+
3
+@implementation RNNAnimationsOptions
4
+
5
+- (instancetype)initWithDict:(NSDictionary *)dict {
6
+	self = [super init];
7
+	
8
+	self.push = [[RNNScreenTransition alloc] initWithDict:dict[@"push"]];
9
+	self.pop = [[RNNScreenTransition alloc] initWithDict:dict[@"pop"]];
10
+	self.showModal = [[RNNScreenTransition alloc] initWithDict:dict[@"showModal"]];
11
+	self.dismissModal = [[RNNScreenTransition alloc] initWithDict:dict[@"dismissModal"]];
12
+	self.setStackRoot = [[RNNScreenTransition alloc] initWithDict:dict[@"setStackRoot"]];
13
+	self.setRoot = [[RNNScreenTransition alloc] initWithDict:dict[@"setRoot"]];
14
+
15
+	return self;
16
+}
17
+
18
+@end

lib/ios/RNNModalAnimation.h → lib/ios/RNNAnimationsTransitionDelegate.h Целия файл

@@ -1,7 +1,7 @@
1 1
 #import <Foundation/Foundation.h>
2 2
 #import "RNNScreenTransition.h"
3 3
 
4
-@interface RNNModalAnimation : NSObject <UIViewControllerAnimatedTransitioning>
4
+@interface RNNAnimationsTransitionDelegate : NSObject <UIViewControllerAnimatedTransitioning, UIViewControllerTransitioningDelegate>
5 5
 
6 6
 @property (nonatomic, strong) RNNScreenTransition* screenTransition;
7 7
 @property (nonatomic) BOOL isDismiss;

+ 60
- 0
lib/ios/RNNAnimationsTransitionDelegate.m Целия файл

@@ -0,0 +1,60 @@
1
+#import "RNNAnimationsTransitionDelegate.h"
2
+
3
+@implementation RNNAnimationsTransitionDelegate
4
+
5
+- (instancetype)initWithScreenTransition:(RNNScreenTransition *)screenTransition isDismiss:(BOOL)isDismiss {
6
+	self = [super init];
7
+	self.screenTransition = screenTransition;
8
+	self.isDismiss = isDismiss;
9
+	return self;
10
+}
11
+
12
+- (nullable id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source {
13
+	return self;
14
+}
15
+
16
+- (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed {
17
+	return self;
18
+}
19
+
20
+- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext {
21
+	return self.screenTransition.maxDuration / 1000;
22
+}
23
+
24
+- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
25
+	UIViewController* toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
26
+	UIViewController* fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
27
+	
28
+	[CATransaction begin];
29
+	[CATransaction setCompletionBlock:^{
30
+		[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
31
+	}];
32
+	
33
+	if (_isDismiss) {
34
+		[[transitionContext containerView] addSubview:toViewController.view];
35
+		[[transitionContext containerView] addSubview:fromViewController.view];
36
+		[self animateElement:self.screenTransition.content view:fromViewController.view elementName:@"content"];
37
+	} else {
38
+		[[transitionContext containerView] addSubview:toViewController.view];
39
+		[self animateElement:self.screenTransition.content view:toViewController.view elementName:@"content"];
40
+	}
41
+	
42
+	[CATransaction commit];
43
+}
44
+
45
+- (void)animationWithKeyPath:(NSString *)keyPath from:(id)from to:(id)to duration:(CFTimeInterval)duration forView:(UIView *)view animationName:(NSString *)animationName {
46
+	CABasicAnimation *animation = [CABasicAnimation animation];
47
+	animation.keyPath = keyPath;
48
+	animation.fromValue = from;
49
+	animation.toValue = to;
50
+	animation.duration = duration / 1000;
51
+	[view.layer addAnimation:animation forKey:animationName];
52
+}
53
+
54
+- (void)animateElement:(RNNElementTransitionOptions *)element view:(UIView *)view elementName:(NSString *)elementName {
55
+	[self animationWithKeyPath:@"position.x" from:@(view.layer.position.x + [element.x.from getWithDefaultValue:0]) to:@(view.layer.position.x + [element.x.to getWithDefaultValue:0]) duration:[element.x.duration getWithDefaultValue:1] forView:view animationName:@"element.position.x"];
56
+	[self animationWithKeyPath:@"position.y" from:@(view.layer.position.y + [element.y.from getWithDefaultValue:0]) to:@(view.layer.position.y + [element.y.to getWithDefaultValue:0]) duration:[element.y.duration getWithDefaultValue:1] forView:view animationName:[NSString stringWithFormat:@"%@.position.y", elementName]];
57
+	[self animationWithKeyPath:@"opacity" from:@([element.alpha.from getWithDefaultValue:1]) to:@([element.alpha.to getWithDefaultValue:1]) duration:[element.alpha.duration getWithDefaultValue:1] forView:view animationName:[NSString stringWithFormat:@"%@.alpha", elementName]];
58
+}
59
+
60
+@end

+ 2
- 2
lib/ios/RNNAnimator.h Целия файл

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

+ 3
- 3
lib/ios/RNNAnimator.m Целия файл

@@ -2,7 +2,7 @@
2 2
 #import "RNNTransition.h"
3 3
 
4 4
 @interface  RNNAnimator()
5
-@property (nonatomic, strong) RNNAnimationOptions* transitionOptions;
5
+@property (nonatomic, strong) RNNSharedElementAnimationOptions* transitionOptions;
6 6
 @property (nonatomic) BOOL backButton;
7 7
 @property (nonatomic, weak) UIViewController* fromVC;
8 8
 @property (nonatomic, weak) UIViewController* toVC;
@@ -10,7 +10,7 @@
10 10
 
11 11
 @implementation RNNAnimator
12 12
 
13
--(instancetype)initWithTransitionOptions:(RNNAnimationOptions *)transitionOptions {
13
+-(instancetype)initWithTransitionOptions:(RNNSharedElementAnimationOptions *)transitionOptions {
14 14
 	self = [super init];
15 15
 	if (transitionOptions.animations) {
16 16
 		[self setupTransition:transitionOptions];
@@ -21,7 +21,7 @@
21 21
 	return self;
22 22
 }
23 23
 
24
--(void)setupTransition:(RNNAnimationOptions *)transitionOptions {
24
+-(void)setupTransition:(RNNSharedElementAnimationOptions *)transitionOptions {
25 25
 	self.transitionOptions = transitionOptions;
26 26
 	if (!transitionOptions.animations) {
27 27
 		[[NSException exceptionWithName:NSInvalidArgumentException reason:@"No animations" userInfo:nil] raise];

+ 18
- 0
lib/ios/RNNElementTransitionOptions.h Целия файл

@@ -0,0 +1,18 @@
1
+#import "RNNOptions.h"
2
+#import "RNNAnimationConfigurationOptions.h"
3
+
4
+@interface RNNElementTransitionOptions : RNNOptions
5
+
6
+@property (nonatomic, strong) RNNAnimationConfigurationOptions* alpha;
7
+@property (nonatomic, strong) RNNAnimationConfigurationOptions* x;
8
+@property (nonatomic, strong) RNNAnimationConfigurationOptions* y;
9
+@property (nonatomic, strong) RNNAnimationConfigurationOptions* scaleX;
10
+@property (nonatomic, strong) RNNAnimationConfigurationOptions* scaleY;
11
+@property (nonatomic, strong) RNNAnimationConfigurationOptions* rotationX;
12
+@property (nonatomic, strong) RNNAnimationConfigurationOptions* rotationY;
13
+@property (nonatomic, strong) Bool* waitForRender;
14
+
15
+- (double)maxDuration;
16
+- (BOOL)hasAnimation;
17
+
18
+@end

+ 34
- 0
lib/ios/RNNElementTransitionOptions.m Целия файл

@@ -0,0 +1,34 @@
1
+#import "RNNElementTransitionOptions.h"
2
+
3
+@implementation RNNElementTransitionOptions
4
+
5
+- (instancetype)initWithDict:(NSDictionary *)dict {
6
+	self = [super init];
7
+	
8
+	self.alpha = [[RNNAnimationConfigurationOptions alloc] initWithDict:dict[@"alpha"]];
9
+	self.x = [[RNNAnimationConfigurationOptions alloc] initWithDict:dict[@"x"]];
10
+	self.y = [[RNNAnimationConfigurationOptions alloc] initWithDict:dict[@"y"]];
11
+
12
+	return self;
13
+}
14
+
15
+- (BOOL)hasAnimation {
16
+	return self.x.hasAnimation || self.y.hasAnimation || self.alpha.hasAnimation;
17
+}
18
+
19
+- (double)maxDuration {
20
+	double maxDuration = 0;
21
+	if ([_x.duration getWithDefaultValue:0] > maxDuration) {
22
+		maxDuration = [_x.duration getWithDefaultValue:0];
23
+	}
24
+	if ([_y.duration getWithDefaultValue:0] > maxDuration) {
25
+		maxDuration = [_y.duration getWithDefaultValue:0];
26
+	}
27
+	if ([_alpha.duration getWithDefaultValue:0] > maxDuration) {
28
+		maxDuration = [_alpha.duration getWithDefaultValue:0];
29
+	}
30
+	
31
+	return maxDuration;
32
+}
33
+
34
+@end

+ 0
- 42
lib/ios/RNNModalAnimation.m Целия файл

@@ -1,42 +0,0 @@
1
-#import "RNNModalAnimation.h"
2
-
3
-@implementation RNNModalAnimation
4
-
5
-- (instancetype)initWithScreenTransition:(RNNScreenTransition *)screenTransition isDismiss:(BOOL)isDismiss {
6
-	self = [super init];
7
-	self.screenTransition = screenTransition;
8
-	self.isDismiss = isDismiss;
9
-	
10
-	return self;
11
-}
12
-
13
-- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext {
14
-	return self.screenTransition.content.duration;
15
-}
16
-
17
-- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
18
-	UIViewController* toViewController = [transitionContext viewControllerForKey:self.isDismiss ? UITransitionContextFromViewControllerKey : UITransitionContextToViewControllerKey];
19
-	UIViewController* fromViewController = [transitionContext viewControllerForKey:self.isDismiss ? UITransitionContextToViewControllerKey : UITransitionContextFromViewControllerKey];
20
-	
21
-	if (self.isDismiss) {
22
-		[[transitionContext containerView] addSubview:fromViewController.view];
23
-		[[transitionContext containerView] addSubview:toViewController.view];
24
-	} else {
25
-		[[transitionContext containerView] addSubview:toViewController.view];
26
-	}
27
-	
28
-	[_screenTransition.content setupInitialTransitionForView:toViewController.view];
29
-	[_screenTransition.topBar setupInitialTransitionForView:toViewController.navigationController.navigationBar];
30
-	
31
-	
32
-	[UIView animateWithDuration:[self transitionDuration:transitionContext] delay:self.screenTransition.content.startDelay options:self.screenTransition.content.interpolation animations:^{
33
-		[_screenTransition.content completeTransitionForView:toViewController.view];
34
-		[_screenTransition.topBar completeTransitionForView:toViewController.navigationController.navigationBar];
35
-	} completion:^(BOOL finished) {
36
-		[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
37
-	}];
38
-}
39
-
40
-
41
-@end
42
-

+ 16
- 5
lib/ios/RNNModalManager.m Целия файл

@@ -1,5 +1,6 @@
1 1
 #import "RNNModalManager.h"
2 2
 #import "RNNRootViewController.h"
3
+#import "RNNAnimationsTransitionDelegate.h"
3 4
 
4 5
 @implementation RNNModalManager {
5 6
 	NSMutableArray* _pendingModalIdsToDismiss;
@@ -19,7 +20,7 @@
19 20
 	[self showModal:viewController animated:animated hasCustomAnimation:NO completion:completion];
20 21
 }
21 22
 
22
--(void)showModal:(UIViewController *)viewController animated:(BOOL)animated hasCustomAnimation:(BOOL)hasCustomAnimation completion:(RNNTransitionWithComponentIdCompletionBlock)completion {
23
+-(void)showModal:(UIViewController<RNNLayoutProtocol> *)viewController animated:(BOOL)animated hasCustomAnimation:(BOOL)hasCustomAnimation completion:(RNNTransitionWithComponentIdCompletionBlock)completion {
23 24
 	if (!viewController) {
24 25
 		@throw [NSException exceptionWithName:@"ShowUnknownModal" reason:@"showModal called with nil viewController" userInfo:nil];
25 26
 	}
@@ -27,8 +28,9 @@
27 28
 	UIViewController* topVC = [self topPresentedVC];
28 29
 	topVC.definesPresentationContext = YES;
29 30
 	
31
+	RNNAnimationsTransitionDelegate* tr = [[RNNAnimationsTransitionDelegate alloc] initWithScreenTransition:viewController.resolveOptions.animations.showModal isDismiss:NO];
30 32
 	if (hasCustomAnimation) {
31
-		viewController.transitioningDelegate = (UIViewController<UIViewControllerTransitioningDelegate>*)topVC;
33
+		viewController.transitioningDelegate = tr;
32 34
 	}
33 35
 	
34 36
 	[topVC presentViewController:viewController animated:animated completion:^{
@@ -67,9 +69,9 @@
67 69
 	}
68 70
 
69 71
 	UIViewController* topPresentedVC = [self topPresentedVC];
70
-
71
-	if ([options.animations.showModal hasCustomAnimation]) {
72
-		modalToDismiss.transitioningDelegate = modalToDismiss;
72
+	RNNAnimationsTransitionDelegate* tr = [[RNNAnimationsTransitionDelegate alloc] initWithScreenTransition:modalToDismiss.resolveOptions.animations.dismissModal isDismiss:YES];
73
+	if ([options.animations.dismissModal hasCustomAnimation]) {
74
+		[self topViewControllerParent:modalToDismiss].transitioningDelegate = tr;
73 75
 	}
74 76
 
75 77
 	if (modalToDismiss == topPresentedVC || [[topPresentedVC childViewControllers] containsObject:modalToDismiss]) {
@@ -115,5 +117,14 @@
115 117
 	return [root topViewController] ? [root topViewController] : root;
116 118
 }
117 119
 
120
+- (UIViewController *)topViewControllerParent:(UIViewController *)viewController {
121
+	UIViewController* topParent = viewController;
122
+	while (topParent.parentViewController) {
123
+		topParent = topParent.parentViewController;
124
+	}
125
+	
126
+	return topParent;
127
+}
128
+
118 129
 
119 130
 @end

+ 0
- 9
lib/ios/RNNNavigationController.m Целия файл

@@ -1,6 +1,5 @@
1 1
 
2 2
 #import "RNNNavigationController.h"
3
-#import "RNNModalAnimation.h"
4 3
 #import "RNNRootViewController.h"
5 4
 #import "InteractivePopGestureDelegate.h"
6 5
 
@@ -107,14 +106,6 @@ const NSInteger TOP_BAR_TRANSPARENT_TAG = 78264803;
107 106
 	return [super popViewControllerAnimated:animated];
108 107
 }
109 108
 
110
-- (nullable id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source {
111
-	return [[RNNModalAnimation alloc] initWithScreenTransition:self.getCurrentChild.resolveOptions.animations.showModal isDismiss:NO];
112
-}
113
-
114
-- (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed {
115
-	return [[RNNModalAnimation alloc] initWithScreenTransition:self.getCurrentChild.resolveOptions.animations.dismissModal isDismiss:YES];
116
-}
117
-
118 109
 - (UIViewController *)getCurrentChild {
119 110
 	return ((UIViewController<RNNParentProtocol>*)self.topViewController);
120 111
 }

+ 4
- 4
lib/ios/RNNNavigationOptions.h Целия файл

@@ -5,8 +5,8 @@
5 5
 #import "RNNTopTabOptions.h"
6 6
 #import "RNNTopTabsOptions.h"
7 7
 #import "RNNOverlayOptions.h"
8
-#import "RNNAnimationOptions.h"
9
-#import "RNNTransitionsOptions.h"
8
+#import "RNNSharedElementAnimationOptions.h"
9
+#import "RNNAnimationsOptions.h"
10 10
 #import "RNNStatusBarOptions.h"
11 11
 #import "RNNPreviewOptions.h"
12 12
 #import "RNNLayoutOptions.h"
@@ -24,8 +24,8 @@ extern const NSInteger TOP_BAR_TRANSPARENT_TAG;
24 24
 @property (nonatomic, strong) RNNTopTabOptions* topTab;
25 25
 @property (nonatomic, strong) RNNSideMenuOptions* sideMenu;
26 26
 @property (nonatomic, strong) RNNOverlayOptions* overlay;
27
-@property (nonatomic, strong) RNNAnimationOptions* customTransition;
28
-@property (nonatomic, strong) RNNTransitionsOptions* animations;
27
+@property (nonatomic, strong) RNNSharedElementAnimationOptions* customTransition;
28
+@property (nonatomic, strong) RNNAnimationsOptions* animations;
29 29
 @property (nonatomic, strong) RNNStatusBarOptions* statusBar;
30 30
 @property (nonatomic, strong) RNNPreviewOptions* preview;
31 31
 @property (nonatomic, strong) RNNLayoutOptions* layout;

+ 2
- 2
lib/ios/RNNNavigationOptions.m Целия файл

@@ -24,8 +24,8 @@
24 24
 	self.sideMenu = [[RNNSideMenuOptions alloc] initWithDict:dict[@"sideMenu"]];
25 25
 	self.splitView = [[RNNSplitViewOptions alloc] initWithDict:dict[@"splitView"]];
26 26
 	self.overlay = [[RNNOverlayOptions alloc] initWithDict:dict[@"overlay"]];
27
-	self.customTransition = [[RNNAnimationOptions alloc] initWithDict:dict[@"customTransition"]];
28
-	self.animations = [[RNNTransitionsOptions alloc] initWithDict:dict[@"animations"]];
27
+	self.customTransition = [[RNNSharedElementAnimationOptions alloc] initWithDict:dict[@"customTransition"]];
28
+	self.animations = [[RNNAnimationsOptions alloc] initWithDict:dict[@"animations"]];
29 29
 	self.statusBar = [[RNNStatusBarOptions alloc] initWithDict:dict[@"statusBar"]];
30 30
 	self.preview = [[RNNPreviewOptions alloc] initWithDict:dict[@"preview"]];
31 31
 	self.layout = [[RNNLayoutOptions alloc] initWithDict:dict[@"layout"]];

+ 4
- 2
lib/ios/RNNPushAnimation.h Целия файл

@@ -1,8 +1,10 @@
1 1
 #import <Foundation/Foundation.h>
2 2
 #import <UIKit/UIKit.h>
3
-#import "RNNModalAnimation.h"
3
+#import "RNNScreenTransition.h"
4 4
 
5
-@interface RNNPushAnimation : RNNModalAnimation <UIViewControllerAnimatedTransitioning>
5
+@interface RNNPushAnimation : NSObject <UIViewControllerAnimatedTransitioning>
6
+
7
+@property (nonatomic, strong) RNNScreenTransition* screenTransition;
6 8
 
7 9
 - (instancetype)initWithScreenTransition:(RNNScreenTransition *)screenTransition;
8 10
 

+ 25
- 12
lib/ios/RNNPushAnimation.m Целия файл

@@ -5,32 +5,45 @@
5 5
 - (instancetype)initWithScreenTransition:(RNNScreenTransition *)screenTransition {
6 6
 	self = [super init];
7 7
 	self.screenTransition = screenTransition;
8
-	
9 8
 	return self;
10 9
 }
11 10
 
12 11
 - (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext {
13
-	return self.screenTransition.content.duration;
12
+	return self.screenTransition.maxDuration / 1000;
14 13
 }
15 14
 
16 15
 - (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
16
+	UIViewController* fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
17 17
 	UIViewController* toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
18 18
 	
19
+	[[transitionContext containerView] addSubview:fromViewController.view];
19 20
 	[[transitionContext containerView] addSubview:toViewController.view];
20 21
 	
21
-	[self.screenTransition.content setupInitialTransitionForView:toViewController.view];
22
-	[self.screenTransition.topBar setupInitialTransitionForView:toViewController.navigationController.navigationBar];
23
-	[self.screenTransition.bottomTabs setupInitialTransitionForView:toViewController.tabBarController.tabBar];
24
-	
25
-	
26
-	[UIView animateWithDuration:[self transitionDuration:transitionContext] delay:self.screenTransition.content.startDelay options:self.screenTransition.content.interpolation animations:^{
27
-		[self.screenTransition.content completeTransitionForView:toViewController.view];
28
-		[self.screenTransition.topBar completeTransitionForView:toViewController.navigationController.navigationBar];
29
-		[self.screenTransition.bottomTabs completeTransitionForView:toViewController.tabBarController.tabBar];
30
-	} completion:^(BOOL finished) {
22
+	[CATransaction begin];
23
+	[CATransaction setCompletionBlock:^{
31 24
 		[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
32 25
 	}];
26
+
27
+	[self animateElement:self.screenTransition.topBar view:toViewController.navigationController.navigationBar elementName:@"topBar"];
28
+	[self animateElement:self.screenTransition.content view:toViewController.view elementName:@"content"];
29
+	[self animateElement:self.screenTransition.bottomTabs view:toViewController.tabBarController.tabBar elementName:@"bottomTabs"];
30
+	
31
+	[CATransaction commit];
32
+}
33
+
34
+- (void)animationWithKeyPath:(NSString *)keyPath from:(id)from to:(id)to duration:(CFTimeInterval)duration forView:(UIView *)view animationName:(NSString *)animationName {
35
+	CABasicAnimation *animation = [CABasicAnimation animation];
36
+	animation.keyPath = keyPath;
37
+	animation.fromValue = from;
38
+	animation.toValue = to;
39
+	animation.duration = duration / 1000;
40
+	[view.layer addAnimation:animation forKey:animationName];
33 41
 }
34 42
 
43
+- (void)animateElement:(RNNElementTransitionOptions *)element view:(UIView *)view elementName:(NSString *)elementName {
44
+	[self animationWithKeyPath:@"position.x" from:@(view.layer.position.x + [element.x.from getWithDefaultValue:0]) to:@(view.layer.position.x + [element.x.to getWithDefaultValue:0]) duration:[element.x.duration getWithDefaultValue:1] forView:view animationName:@"element.position.x"];
45
+	[self animationWithKeyPath:@"position.y" from:@(view.layer.position.y + [element.y.from getWithDefaultValue:0]) to:@(view.layer.position.y + [element.y.to getWithDefaultValue:0]) duration:[element.y.duration getWithDefaultValue:1] forView:view animationName:[NSString stringWithFormat:@"%@.position.y", elementName]];
46
+	[self animationWithKeyPath:@"opacity" from:@([element.alpha.from getWithDefaultValue:1]) to:@([element.alpha.to getWithDefaultValue:1]) duration:[element.alpha.duration getWithDefaultValue:1] forView:view animationName:[NSString stringWithFormat:@"%@.alpha", elementName]];
47
+}
35 48
 
36 49
 @end

+ 3
- 12
lib/ios/RNNRootViewController.m Целия файл

@@ -4,7 +4,7 @@
4 4
 #import "RNNPushAnimation.h"
5 5
 #import "RNNReactView.h"
6 6
 #import "RNNParentProtocol.h"
7
-
7
+#import "RNNAnimationsTransitionDelegate.h"
8 8
 
9 9
 @implementation RNNRootViewController
10 10
 
@@ -172,9 +172,9 @@
172 172
 	if (self.animator) {
173 173
 		return self.animator;
174 174
 	} else if (operation == UINavigationControllerOperationPush && self.resolveOptions.animations.push.hasCustomAnimation) {
175
-		return [[RNNPushAnimation alloc] initWithScreenTransition:self.resolveOptions.animations.push];
175
+		return [[RNNAnimationsTransitionDelegate alloc] initWithScreenTransition:self.resolveOptions.animations.push isDismiss:NO];
176 176
 	} else if (operation == UINavigationControllerOperationPop && self.resolveOptions.animations.pop.hasCustomAnimation) {
177
-		return [[RNNPushAnimation alloc] initWithScreenTransition:self.resolveOptions.animations.pop];
177
+		return [[RNNAnimationsTransitionDelegate alloc] initWithScreenTransition:self.resolveOptions.animations.pop isDismiss:YES];
178 178
 	} else {
179 179
 		return nil;
180 180
 	}
@@ -182,19 +182,10 @@
182 182
 	return nil;
183 183
 }
184 184
 
185
-- (nullable id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source {
186
-	return [[RNNModalAnimation alloc] initWithScreenTransition:self.resolveOptions.animations.showModal isDismiss:NO];
187
-}
188
-
189
-- (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed {
190
-	return [[RNNModalAnimation alloc] initWithScreenTransition:self.resolveOptions.animations.dismissModal isDismiss:YES];
191
-}
192
-
193 185
 - (UIViewController *)previewingContext:(id<UIViewControllerPreviewing>)previewingContext viewControllerForLocation:(CGPoint)location{
194 186
 	return self.previewController;
195 187
 }
196 188
 
197
-
198 189
 - (void)previewingContext:(id<UIViewControllerPreviewing>)previewingContext commitViewController:(UIViewController *)viewControllerToCommit {
199 190
 	if (self.previewCallback) {
200 191
 		self.previewCallback(self);

+ 5
- 4
lib/ios/RNNScreenTransition.h Целия файл

@@ -1,15 +1,16 @@
1 1
 #import "RNNOptions.h"
2
-#import "RNNTransitionStateHolder.h"
2
+#import "RNNElementTransitionOptions.h"
3 3
 
4 4
 @interface RNNScreenTransition : RNNOptions
5 5
 
6
-@property (nonatomic, strong) RNNTransitionStateHolder* topBar;
7
-@property (nonatomic, strong) RNNTransitionStateHolder* content;
8
-@property (nonatomic, strong) RNNTransitionStateHolder* bottomTabs;
6
+@property (nonatomic, strong) RNNElementTransitionOptions* topBar;
7
+@property (nonatomic, strong) RNNElementTransitionOptions* content;
8
+@property (nonatomic, strong) RNNElementTransitionOptions* bottomTabs;
9 9
 
10 10
 @property (nonatomic, strong) Bool* enable;
11 11
 @property (nonatomic, strong) Bool* waitForRender;
12 12
 
13 13
 - (BOOL)hasCustomAnimation;
14
+- (double)maxDuration;
14 15
 
15 16
 @end

+ 19
- 4
lib/ios/RNNScreenTransition.m Целия файл

@@ -5,9 +5,9 @@
5 5
 - (instancetype)initWithDict:(NSDictionary *)dict {
6 6
 	self = [super init];
7 7
 
8
-	self.topBar = dict[@"topBar"] ? [[RNNTransitionStateHolder alloc] initWithDict:dict[@"topBar"]] : nil;
9
-	self.content = dict[@"content"] ? [[RNNTransitionStateHolder alloc] initWithDict:dict[@"content"]] : nil;
10
-	self.bottomTabs = dict[@"bottomTabs"] ? [[RNNTransitionStateHolder alloc] initWithDict:dict[@"bottomTabs"]] : nil;
8
+	self.topBar = [[RNNElementTransitionOptions alloc] initWithDict:dict[@"topBar"]];
9
+	self.content = [[RNNElementTransitionOptions alloc] initWithDict:dict[@"content"]];
10
+	self.bottomTabs = [[RNNElementTransitionOptions alloc] initWithDict:dict[@"bottomTabs"]];
11 11
 	self.enable = [BoolParser parse:dict key:@"enabled"];
12 12
 	self.waitForRender = [BoolParser parse:dict key:@"waitForRender"];
13 13
 
@@ -15,7 +15,22 @@
15 15
 }
16 16
 
17 17
 - (BOOL)hasCustomAnimation {
18
-	return (self.topBar || self.content || self.bottomTabs);
18
+	return (self.topBar.hasAnimation || self.content.hasAnimation || self.bottomTabs.hasAnimation);
19
+}
20
+
21
+- (double)maxDuration {
22
+	double maxDuration = 0;
23
+	if ([self.topBar maxDuration] > 0) {
24
+		maxDuration = [self.topBar maxDuration];
25
+	}
26
+	if ([self.content maxDuration] > 0) {
27
+		maxDuration = [self.content maxDuration];
28
+	}
29
+	if ([self.bottomTabs maxDuration] > 0) {
30
+		maxDuration = [self.bottomTabs maxDuration];
31
+	}
32
+	
33
+	return maxDuration;
19 34
 }
20 35
 
21 36
 @end

lib/ios/RNNAnimationOptions.h → lib/ios/RNNSharedElementAnimationOptions.h Целия файл

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

lib/ios/RNNAnimationOptions.m → lib/ios/RNNSharedElementAnimationOptions.m Целия файл

@@ -1,10 +1,10 @@
1
-#import "RNNAnimationOptions.h"
1
+#import "RNNSharedElementAnimationOptions.h"
2 2
 
3 3
 #define DEFAULT_DURATION @(0.7)
4 4
 #define DEFAULT_SPRING_VELOCITY @(0.8)
5 5
 #define DEFAULT_SPRING_DAMPING @(0.85)
6 6
 
7
-@implementation RNNAnimationOptions
7
+@implementation RNNSharedElementAnimationOptions
8 8
 
9 9
 - (instancetype)initWithDict:(NSDictionary *)dict {
10 10
 	self = [super init];

+ 2
- 2
lib/ios/RNNTransitionsOptions.m Целия файл

@@ -1,6 +1,6 @@
1
-#import "RNNTransitionsOptions.h"
1
+#import "RNNAnimationsOptions.h"
2 2
 
3
-@implementation RNNTransitionsOptions
3
+@implementation RNNAnimationsOptions
4 4
 
5 5
 - (instancetype)initWithDict:(NSDictionary *)dict {
6 6
 	self = [super init];

+ 40
- 24
lib/ios/ReactNativeNavigation.xcodeproj/project.pbxproj Целия файл

@@ -136,8 +136,8 @@
136 136
 		50415CBB20553B8E00BB682E /* RNNScreenTransition.m in Sources */ = {isa = PBXBuildFile; fileRef = 50415CB920553B8E00BB682E /* RNNScreenTransition.m */; };
137 137
 		50451D052042DAEB00695F00 /* RNNPushAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = 50451D032042DAEB00695F00 /* RNNPushAnimation.h */; };
138 138
 		50451D062042DAEB00695F00 /* RNNPushAnimation.m in Sources */ = {isa = PBXBuildFile; fileRef = 50451D042042DAEB00695F00 /* RNNPushAnimation.m */; };
139
-		50451D092042E20600695F00 /* RNNTransitionsOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 50451D072042E20600695F00 /* RNNTransitionsOptions.h */; };
140
-		50451D0A2042E20600695F00 /* RNNTransitionsOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 50451D082042E20600695F00 /* RNNTransitionsOptions.m */; };
139
+		50451D092042E20600695F00 /* RNNAnimationsOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 50451D072042E20600695F00 /* RNNAnimationsOptions.h */; };
140
+		50451D0A2042E20600695F00 /* RNNAnimationsOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 50451D082042E20600695F00 /* RNNAnimationsOptions.m */; };
141 141
 		50451D0D2042F70900695F00 /* RNNTransition.h in Headers */ = {isa = PBXBuildFile; fileRef = 50451D0B2042F70900695F00 /* RNNTransition.h */; };
142 142
 		50451D0E2042F70900695F00 /* RNNTransition.m in Sources */ = {isa = PBXBuildFile; fileRef = 50451D0C2042F70900695F00 /* RNNTransition.m */; };
143 143
 		504753782109C13C00FFFBE6 /* RNNOverlayManagerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 504753772109C13C00FFFBE6 /* RNNOverlayManagerTest.m */; };
@@ -195,10 +195,8 @@
195 195
 		506F630F216A5AD700AD0D0A /* RNNViewControllerPresenterTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 506F630E216A5AD700AD0D0A /* RNNViewControllerPresenterTest.m */; };
196 196
 		50706E6D20CE7CA5003345C3 /* UIImage+tint.h in Headers */ = {isa = PBXBuildFile; fileRef = 50706E6B20CE7CA5003345C3 /* UIImage+tint.h */; };
197 197
 		50706E6E20CE7CA5003345C3 /* UIImage+tint.m in Sources */ = {isa = PBXBuildFile; fileRef = 50706E6C20CE7CA5003345C3 /* UIImage+tint.m */; };
198
-		50762D08205E96C200E3D18A /* RNNModalAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = 50762D06205E96C200E3D18A /* RNNModalAnimation.h */; };
199
-		50762D09205E96C200E3D18A /* RNNModalAnimation.m in Sources */ = {isa = PBXBuildFile; fileRef = 50762D07205E96C200E3D18A /* RNNModalAnimation.m */; };
200
-		507E7D57201DDD3000444E6C /* RNNAnimationOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 507E7D55201DDD3000444E6C /* RNNAnimationOptions.h */; };
201
-		507E7D58201DDD3000444E6C /* RNNAnimationOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 507E7D56201DDD3000444E6C /* RNNAnimationOptions.m */; };
198
+		507E7D57201DDD3000444E6C /* RNNSharedElementAnimationOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 507E7D55201DDD3000444E6C /* RNNSharedElementAnimationOptions.h */; };
199
+		507E7D58201DDD3000444E6C /* RNNSharedElementAnimationOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 507E7D56201DDD3000444E6C /* RNNSharedElementAnimationOptions.m */; };
202 200
 		507F43C51FF4F17C00D9425B /* RNNTopTabsViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 507F43C31FF4F17C00D9425B /* RNNTopTabsViewController.h */; };
203 201
 		507F43C61FF4F17C00D9425B /* RNNTopTabsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 507F43C41FF4F17C00D9425B /* RNNTopTabsViewController.m */; };
204 202
 		507F43C91FF4F9CC00D9425B /* RNNTopTabOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 507F43C71FF4F9CC00D9425B /* RNNTopTabOptions.h */; };
@@ -232,6 +230,12 @@
232 230
 		50E02BD921A6EE0F00A43942 /* SideMenuOpenMode.m in Sources */ = {isa = PBXBuildFile; fileRef = 50E02BD721A6EE0F00A43942 /* SideMenuOpenMode.m */; };
233 231
 		50E02BDC21A6EE7900A43942 /* SideMenuOpenGestureModeParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 50E02BDA21A6EE7900A43942 /* SideMenuOpenGestureModeParser.m */; };
234 232
 		50E02BDD21A6EE7900A43942 /* SideMenuOpenGestureModeParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 50E02BDB21A6EE7900A43942 /* SideMenuOpenGestureModeParser.h */; };
233
+		50E5F78D223F9FAF002AFEAD /* RNNElementTransitionOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 50E5F78B223F9FAF002AFEAD /* RNNElementTransitionOptions.h */; };
234
+		50E5F78E223F9FAF002AFEAD /* RNNElementTransitionOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 50E5F78C223F9FAF002AFEAD /* RNNElementTransitionOptions.m */; };
235
+		50E5F791223FA04C002AFEAD /* RNNAnimationConfigurationOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 50E5F78F223FA04C002AFEAD /* RNNAnimationConfigurationOptions.h */; };
236
+		50E5F792223FA04C002AFEAD /* RNNAnimationConfigurationOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 50E5F790223FA04C002AFEAD /* RNNAnimationConfigurationOptions.m */; };
237
+		50E5F7952240EBD6002AFEAD /* RNNAnimationsTransitionDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 50E5F7932240EBD6002AFEAD /* RNNAnimationsTransitionDelegate.h */; };
238
+		50E5F7962240EBD6002AFEAD /* RNNAnimationsTransitionDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 50E5F7942240EBD6002AFEAD /* RNNAnimationsTransitionDelegate.m */; };
235 239
 		50EB4ED72068EBE000D6ED34 /* RNNBackgroundOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 50EB4ED52068EBE000D6ED34 /* RNNBackgroundOptions.h */; };
236 240
 		50EB4ED82068EBE000D6ED34 /* RNNBackgroundOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 50EB4ED62068EBE000D6ED34 /* RNNBackgroundOptions.m */; };
237 241
 		50EB93421FE14A3E00BD8EEE /* RNNBottomTabOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 50EB93401FE14A3E00BD8EEE /* RNNBottomTabOptions.m */; };
@@ -471,8 +475,8 @@
471 475
 		50415CB920553B8E00BB682E /* RNNScreenTransition.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNScreenTransition.m; sourceTree = "<group>"; };
472 476
 		50451D032042DAEB00695F00 /* RNNPushAnimation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNPushAnimation.h; sourceTree = "<group>"; };
473 477
 		50451D042042DAEB00695F00 /* RNNPushAnimation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNPushAnimation.m; sourceTree = "<group>"; };
474
-		50451D072042E20600695F00 /* RNNTransitionsOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNTransitionsOptions.h; sourceTree = "<group>"; };
475
-		50451D082042E20600695F00 /* RNNTransitionsOptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNTransitionsOptions.m; sourceTree = "<group>"; };
478
+		50451D072042E20600695F00 /* RNNAnimationsOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNAnimationsOptions.h; sourceTree = "<group>"; };
479
+		50451D082042E20600695F00 /* RNNAnimationsOptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNAnimationsOptions.m; sourceTree = "<group>"; };
476 480
 		50451D0B2042F70900695F00 /* RNNTransition.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNTransition.h; sourceTree = "<group>"; };
477 481
 		50451D0C2042F70900695F00 /* RNNTransition.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNTransition.m; sourceTree = "<group>"; };
478 482
 		504753772109C13C00FFFBE6 /* RNNOverlayManagerTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNNOverlayManagerTest.m; sourceTree = "<group>"; };
@@ -528,10 +532,8 @@
528 532
 		506F630E216A5AD700AD0D0A /* RNNViewControllerPresenterTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNViewControllerPresenterTest.m; sourceTree = "<group>"; };
529 533
 		50706E6B20CE7CA5003345C3 /* UIImage+tint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UIImage+tint.h"; sourceTree = "<group>"; };
530 534
 		50706E6C20CE7CA5003345C3 /* UIImage+tint.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UIImage+tint.m"; sourceTree = "<group>"; };
531
-		50762D06205E96C200E3D18A /* RNNModalAnimation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNModalAnimation.h; sourceTree = "<group>"; };
532
-		50762D07205E96C200E3D18A /* RNNModalAnimation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNModalAnimation.m; sourceTree = "<group>"; };
533
-		507E7D55201DDD3000444E6C /* RNNAnimationOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNAnimationOptions.h; sourceTree = "<group>"; };
534
-		507E7D56201DDD3000444E6C /* RNNAnimationOptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNAnimationOptions.m; sourceTree = "<group>"; };
535
+		507E7D55201DDD3000444E6C /* RNNSharedElementAnimationOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNSharedElementAnimationOptions.h; sourceTree = "<group>"; };
536
+		507E7D56201DDD3000444E6C /* RNNSharedElementAnimationOptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNSharedElementAnimationOptions.m; sourceTree = "<group>"; };
535 537
 		507F43C31FF4F17C00D9425B /* RNNTopTabsViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNTopTabsViewController.h; sourceTree = "<group>"; };
536 538
 		507F43C41FF4F17C00D9425B /* RNNTopTabsViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNTopTabsViewController.m; sourceTree = "<group>"; };
537 539
 		507F43C71FF4F9CC00D9425B /* RNNTopTabOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNTopTabOptions.h; sourceTree = "<group>"; };
@@ -564,6 +566,12 @@
564 566
 		50E02BD721A6EE0F00A43942 /* SideMenuOpenMode.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SideMenuOpenMode.m; sourceTree = "<group>"; };
565 567
 		50E02BDA21A6EE7900A43942 /* SideMenuOpenGestureModeParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SideMenuOpenGestureModeParser.m; sourceTree = "<group>"; };
566 568
 		50E02BDB21A6EE7900A43942 /* SideMenuOpenGestureModeParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SideMenuOpenGestureModeParser.h; sourceTree = "<group>"; };
569
+		50E5F78B223F9FAF002AFEAD /* RNNElementTransitionOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNElementTransitionOptions.h; sourceTree = "<group>"; };
570
+		50E5F78C223F9FAF002AFEAD /* RNNElementTransitionOptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNElementTransitionOptions.m; sourceTree = "<group>"; };
571
+		50E5F78F223FA04C002AFEAD /* RNNAnimationConfigurationOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNAnimationConfigurationOptions.h; sourceTree = "<group>"; };
572
+		50E5F790223FA04C002AFEAD /* RNNAnimationConfigurationOptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNAnimationConfigurationOptions.m; sourceTree = "<group>"; };
573
+		50E5F7932240EBD6002AFEAD /* RNNAnimationsTransitionDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNAnimationsTransitionDelegate.h; sourceTree = "<group>"; };
574
+		50E5F7942240EBD6002AFEAD /* RNNAnimationsTransitionDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNAnimationsTransitionDelegate.m; sourceTree = "<group>"; };
567 575
 		50EB4ED52068EBE000D6ED34 /* RNNBackgroundOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNBackgroundOptions.h; sourceTree = "<group>"; };
568 576
 		50EB4ED62068EBE000D6ED34 /* RNNBackgroundOptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNBackgroundOptions.m; sourceTree = "<group>"; };
569 577
 		50EB933F1FE14A3E00BD8EEE /* RNNBottomTabOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNBottomTabOptions.h; sourceTree = "<group>"; };
@@ -915,6 +923,10 @@
915 923
 				50570B252061473D006A1B5C /* RNNTitleOptions.m */,
916 924
 				50C4A494206BDDBB00DB292E /* RNNSubtitleOptions.h */,
917 925
 				50C4A495206BDDBB00DB292E /* RNNSubtitleOptions.m */,
926
+				50E5F78B223F9FAF002AFEAD /* RNNElementTransitionOptions.h */,
927
+				50E5F78C223F9FAF002AFEAD /* RNNElementTransitionOptions.m */,
928
+				50E5F78F223FA04C002AFEAD /* RNNAnimationConfigurationOptions.h */,
929
+				50E5F790223FA04C002AFEAD /* RNNAnimationConfigurationOptions.m */,
918 930
 				5048862B20BE976D000908DE /* RNNLayoutOptions.h */,
919 931
 				5048862C20BE976D000908DE /* RNNLayoutOptions.m */,
920 932
 				50BE951120B5A787004F5DF5 /* RNNStatusBarOptions.h */,
@@ -935,12 +947,12 @@
935 947
 				5064495C20DC62B90026709C /* RNNSideMenuSideOptions.m */,
936 948
 				50A00C35200F84D6000F01A6 /* RNNOverlayOptions.h */,
937 949
 				50A00C36200F84D6000F01A6 /* RNNOverlayOptions.m */,
938
-				507E7D55201DDD3000444E6C /* RNNAnimationOptions.h */,
939
-				507E7D56201DDD3000444E6C /* RNNAnimationOptions.m */,
950
+				507E7D55201DDD3000444E6C /* RNNSharedElementAnimationOptions.h */,
951
+				507E7D56201DDD3000444E6C /* RNNSharedElementAnimationOptions.m */,
940 952
 				E8E5182C1F83A48B000467AC /* RNNTransitionStateHolder.h */,
941 953
 				E8E5182D1F83A48B000467AC /* RNNTransitionStateHolder.m */,
942
-				50451D072042E20600695F00 /* RNNTransitionsOptions.h */,
943
-				50451D082042E20600695F00 /* RNNTransitionsOptions.m */,
954
+				50451D072042E20600695F00 /* RNNAnimationsOptions.h */,
955
+				50451D082042E20600695F00 /* RNNAnimationsOptions.m */,
944 956
 				50415CB820553B8E00BB682E /* RNNScreenTransition.h */,
945 957
 				50415CB920553B8E00BB682E /* RNNScreenTransition.m */,
946 958
 				E33AC20620B5C49E0090DB8A /* RNNSplitViewOptions.h */,
@@ -1168,8 +1180,8 @@
1168 1180
 				E8DA243F1F97459B00CD552B /* RNNElementFinder.m */,
1169 1181
 				50451D032042DAEB00695F00 /* RNNPushAnimation.h */,
1170 1182
 				50451D042042DAEB00695F00 /* RNNPushAnimation.m */,
1171
-				50762D06205E96C200E3D18A /* RNNModalAnimation.h */,
1172
-				50762D07205E96C200E3D18A /* RNNModalAnimation.m */,
1183
+				50E5F7932240EBD6002AFEAD /* RNNAnimationsTransitionDelegate.h */,
1184
+				50E5F7942240EBD6002AFEAD /* RNNAnimationsTransitionDelegate.m */,
1173 1185
 			);
1174 1186
 			name = Animations;
1175 1187
 			sourceTree = "<group>";
@@ -1231,6 +1243,7 @@
1231 1243
 				50E02BDD21A6EE7900A43942 /* SideMenuOpenGestureModeParser.h in Headers */,
1232 1244
 				263905BD1E4C6F440023D7D3 /* RCCDrawerProtocol.h in Headers */,
1233 1245
 				5038A3B5216DF602009280BC /* UINavigationController+RNNOptions.h in Headers */,
1246
+				50E5F78D223F9FAF002AFEAD /* RNNElementTransitionOptions.h in Headers */,
1234 1247
 				5038A3C1216E1E66009280BC /* RNNFontAttributesCreator.h in Headers */,
1235 1248
 				5016E8EF20209690009D4F7C /* RNNCustomTitleView.h in Headers */,
1236 1249
 				50415CBA20553B8E00BB682E /* RNNScreenTransition.h in Headers */,
@@ -1267,6 +1280,7 @@
1267 1280
 				263905BE1E4C6F440023D7D3 /* RCCTheSideBarManagerViewController.h in Headers */,
1268 1281
 				263905CE1E4C6F440023D7D3 /* TheSidebarController.h in Headers */,
1269 1282
 				50D031342005149000386B3D /* RNNOverlayManager.h in Headers */,
1283
+				50E5F7952240EBD6002AFEAD /* RNNAnimationsTransitionDelegate.h in Headers */,
1270 1284
 				7B1126A71E2D2B6C00F9B03B /* RNNEventEmitter.h in Headers */,
1271 1285
 				E8A430111F9CB87B00B61A20 /* RNNAnimatedView.h in Headers */,
1272 1286
 				506317AA220B547400B26FC3 /* UIImage+insets.h in Headers */,
@@ -1278,6 +1292,7 @@
1278 1292
 				268692821E5054F800E2C612 /* RNNStore.h in Headers */,
1279 1293
 				E8AEDB3C1F55A1C2000F5A6A /* RNNElementView.h in Headers */,
1280 1294
 				E8E518321F83B3E0000467AC /* RNNUtils.h in Headers */,
1295
+				50E5F791223FA04C002AFEAD /* RNNAnimationConfigurationOptions.h in Headers */,
1281 1296
 				5049594E216F6277006D2B81 /* NumberParser.h in Headers */,
1282 1297
 				50BE951320B5A787004F5DF5 /* RNNStatusBarOptions.h in Headers */,
1283 1298
 				507F44201FFA8A8800D9425B /* RNNParentProtocol.h in Headers */,
@@ -1285,12 +1300,11 @@
1285 1300
 				263905CA1E4C6F440023D7D3 /* SidebarLuvocracyAnimation.h in Headers */,
1286 1301
 				50495956216F6B3D006D2B81 /* DictionaryParser.h in Headers */,
1287 1302
 				4534E72520CB6724009F8185 /* RNNLargeTitleOptions.h in Headers */,
1288
-				50762D08205E96C200E3D18A /* RNNModalAnimation.h in Headers */,
1289 1303
 				390AD477200F499D00A8250D /* RNNSwizzles.h in Headers */,
1290 1304
 				263905B11E4C6F440023D7D3 /* MMDrawerController.h in Headers */,
1291 1305
 				263905B91E4C6F440023D7D3 /* RCCDrawerController.h in Headers */,
1292 1306
 				263905B31E4C6F440023D7D3 /* MMDrawerVisualState.h in Headers */,
1293
-				50451D092042E20600695F00 /* RNNTransitionsOptions.h in Headers */,
1307
+				50451D092042E20600695F00 /* RNNAnimationsOptions.h in Headers */,
1294 1308
 				5048862D20BE976D000908DE /* RNNLayoutOptions.h in Headers */,
1295 1309
 				5038A374216CDDB6009280BC /* UIViewController+SideMenuController.h in Headers */,
1296 1310
 				E8A5CD621F49114F00E89D0D /* RNNElement.h in Headers */,
@@ -1306,7 +1320,7 @@
1306 1320
 				5039558F217482FE00B0A663 /* NullIntNumber.h in Headers */,
1307 1321
 				5038A3CA216E328A009280BC /* Param.h in Headers */,
1308 1322
 				50887CAA20F26BFE00D06111 /* RNNOverlayWindow.h in Headers */,
1309
-				507E7D57201DDD3000444E6C /* RNNAnimationOptions.h in Headers */,
1323
+				507E7D57201DDD3000444E6C /* RNNSharedElementAnimationOptions.h in Headers */,
1310 1324
 				5053CE7F2175FB1900D0386B /* RNNDefaultOptionsHelper.h in Headers */,
1311 1325
 				2DCD9195200014A900EDC75D /* RNNBridgeManager.h in Headers */,
1312 1326
 				7B1126A91E2D2B6C00F9B03B /* RNNControllerFactory.h in Headers */,
@@ -1456,6 +1470,7 @@
1456 1470
 				263905B41E4C6F440023D7D3 /* MMDrawerVisualState.m in Sources */,
1457 1471
 				5012240B21735959000F5F98 /* RNNSideMenuPresenter.m in Sources */,
1458 1472
 				502CB46F20CD1DDA0019B2FE /* RNNBackButtonOptions.m in Sources */,
1473
+				50E5F78E223F9FAF002AFEAD /* RNNElementTransitionOptions.m in Sources */,
1459 1474
 				7365071221E4B16F004E020F /* RCTConvert+UIBarButtonSystemItem.m in Sources */,
1460 1475
 				5012241B21736678000F5F98 /* Image.m in Sources */,
1461 1476
 				50495943216F5E5D006D2B81 /* NullBool.m in Sources */,
@@ -1491,6 +1506,7 @@
1491 1506
 				390AD478200F499D00A8250D /* RNNSwizzles.m in Sources */,
1492 1507
 				50E02BD921A6EE0F00A43942 /* SideMenuOpenMode.m in Sources */,
1493 1508
 				7BA500751E2544B9001B9E1B /* ReactNativeNavigation.m in Sources */,
1509
+				50E5F7962240EBD6002AFEAD /* RNNAnimationsTransitionDelegate.m in Sources */,
1494 1510
 				5038A3BA216DFCFD009280BC /* UITabBarController+RNNOptions.m in Sources */,
1495 1511
 				263905B21E4C6F440023D7D3 /* MMDrawerController.m in Sources */,
1496 1512
 				50644A2120E11A720026709C /* Constants.m in Sources */,
@@ -1525,7 +1541,7 @@
1525 1541
 				C2A57A1D21E815F80066711C /* InteractivePopGestureDelegate.m in Sources */,
1526 1542
 				263905BC1E4C6F440023D7D3 /* RCCDrawerHelper.m in Sources */,
1527 1543
 				4534E72620CB6724009F8185 /* RNNLargeTitleOptions.m in Sources */,
1528
-				507E7D58201DDD3000444E6C /* RNNAnimationOptions.m in Sources */,
1544
+				507E7D58201DDD3000444E6C /* RNNSharedElementAnimationOptions.m in Sources */,
1529 1545
 				2145452A1F4DC85F006E8DA1 /* RCTHelpers.m in Sources */,
1530 1546
 				2DCD9196200014A900EDC75D /* RNNBridgeManager.m in Sources */,
1531 1547
 				263905C11E4C6F440023D7D3 /* SidebarAirbnbAnimation.m in Sources */,
@@ -1546,16 +1562,16 @@
1546 1562
 				E8A430121F9CB87B00B61A20 /* RNNAnimatedView.m in Sources */,
1547 1563
 				507F43F51FF4FCFE00D9425B /* HMSegmentedControl.m in Sources */,
1548 1564
 				5012242321736883000F5F98 /* NullColor.m in Sources */,
1549
-				50451D0A2042E20600695F00 /* RNNTransitionsOptions.m in Sources */,
1565
+				50451D0A2042E20600695F00 /* RNNAnimationsOptions.m in Sources */,
1550 1566
 				5039558C2174829400B0A663 /* IntNumberParser.m in Sources */,
1551 1567
 				507F43C61FF4F17C00D9425B /* RNNTopTabsViewController.m in Sources */,
1552 1568
 				50706E6E20CE7CA5003345C3 /* UIImage+tint.m in Sources */,
1553 1569
 				501224072173592D000F5F98 /* RNNTabBarPresenter.m in Sources */,
1554 1570
 				50A00C38200F84D6000F01A6 /* RNNOverlayOptions.m in Sources */,
1555
-				50762D09205E96C200E3D18A /* RNNModalAnimation.m in Sources */,
1556 1571
 				5039559C2174867000B0A663 /* DoubleParser.m in Sources */,
1557 1572
 				5049593F216F5D73006D2B81 /* BoolParser.m in Sources */,
1558 1573
 				50EB93421FE14A3E00BD8EEE /* RNNBottomTabOptions.m in Sources */,
1574
+				50E5F792223FA04C002AFEAD /* RNNAnimationConfigurationOptions.m in Sources */,
1559 1575
 				5049595B216F6B46006D2B81 /* NullDictionary.m in Sources */,
1560 1576
 				5038A3BE216E1490009280BC /* RNNTabBarItemCreator.m in Sources */,
1561 1577
 				E8367B811F7A8A4700675C05 /* VICMAImageView.m in Sources */,