react-native-screens 3.10.1 → 3.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +13 -7
  3. package/RNScreens.podspec +36 -6
  4. package/android/build.gradle +74 -3
  5. package/android/src/fabric/java/com/swmansion/rnscreens/FabricEnabledViewGroup.kt +49 -0
  6. package/android/src/fabric/java/com/swmansion/rnscreens/RNScreensComponentsRegistry.java +28 -0
  7. package/android/src/main/java/com/swmansion/rnscreens/RNScreensPackage.kt +11 -2
  8. package/android/src/main/java/com/swmansion/rnscreens/Screen.kt +52 -21
  9. package/android/src/main/java/com/swmansion/rnscreens/ScreenContainer.kt +1 -1
  10. package/android/src/main/java/com/swmansion/rnscreens/ScreenFragment.kt +64 -33
  11. package/android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt +9 -31
  12. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragment.kt +0 -30
  13. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfig.kt +12 -5
  14. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfigViewManager.kt +83 -18
  15. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderSubviewManager.kt +17 -5
  16. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackViewManager.kt +14 -1
  17. package/android/src/main/java/com/swmansion/rnscreens/ScreenViewManager.kt +41 -14
  18. package/android/src/main/java/com/swmansion/rnscreens/ScreenWindowTraits.kt +72 -11
  19. package/android/src/main/java/com/swmansion/rnscreens/SearchBarManager.kt +18 -1
  20. package/android/src/main/java/com/swmansion/rnscreens/SearchBarView.kt +7 -2
  21. package/android/src/main/java/com/swmansion/rnscreens/SearchViewFormatter.kt +29 -2
  22. package/android/src/main/jni/Android.mk +45 -0
  23. package/android/src/main/jni/OnLoad.cpp +9 -0
  24. package/android/src/main/jni/RNScreensComponentsRegistry.cpp +66 -0
  25. package/android/src/main/jni/RNScreensComponentsRegistry.h +34 -0
  26. package/android/src/main/res/anim/rns_default_enter_in.xml +18 -0
  27. package/android/src/main/res/anim/rns_default_enter_out.xml +19 -0
  28. package/android/src/main/res/anim/rns_default_exit_in.xml +17 -0
  29. package/android/src/main/res/anim/rns_default_exit_out.xml +18 -0
  30. package/android/src/main/res/anim/rns_fade_in.xml +7 -0
  31. package/android/src/main/res/anim/rns_fade_out.xml +7 -0
  32. package/android/src/main/res/anim/rns_no_animation_20.xml +6 -0
  33. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenManagerDelegate.java +71 -0
  34. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenManagerInterface.java +30 -0
  35. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackHeaderConfigManagerDelegate.java +104 -0
  36. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackHeaderConfigManagerInterface.java +41 -0
  37. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackHeaderSubviewManagerDelegate.java +31 -0
  38. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackHeaderSubviewManagerInterface.java +17 -0
  39. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackManagerDelegate.java +25 -0
  40. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackManagerInterface.java +16 -0
  41. package/android/src/paper/java/com/swmansion/rnscreens/FabricEnabledViewGroup.kt +16 -0
  42. package/common/cpp/Android.mk +38 -0
  43. package/common/cpp/rnscreens/RNSScreenComponentDescriptor.h +41 -0
  44. package/common/cpp/rnscreens/RNSScreenShadowNode.cpp +9 -0
  45. package/common/cpp/rnscreens/RNSScreenShadowNode.h +29 -0
  46. package/common/cpp/rnscreens/RNSScreenState.cpp +14 -0
  47. package/common/cpp/rnscreens/RNSScreenState.h +46 -0
  48. package/createNativeStackNavigator/README.md +12 -0
  49. package/ios/RNSScreen.h +10 -0
  50. package/ios/RNSScreen.m +34 -0
  51. package/ios/RNSScreenComponentView.h +23 -0
  52. package/ios/RNSScreenComponentView.mm +159 -0
  53. package/ios/RNSScreenContainer.m +5 -0
  54. package/ios/RNSScreenController.h +10 -0
  55. package/ios/RNSScreenController.mm +79 -0
  56. package/ios/RNSScreenStack.m +22 -7
  57. package/ios/RNSScreenStackAnimator.m +45 -14
  58. package/ios/RNSScreenStackComponentView.h +15 -0
  59. package/ios/RNSScreenStackComponentView.mm +295 -0
  60. package/ios/RNSScreenStackHeaderConfig.m +4 -1
  61. package/ios/RNSScreenStackHeaderConfigComponentView.h +42 -0
  62. package/ios/RNSScreenStackHeaderConfigComponentView.mm +662 -0
  63. package/ios/RNSScreenStackHeaderSubviewComponentView.h +14 -0
  64. package/ios/RNSScreenStackHeaderSubviewComponentView.mm +77 -0
  65. package/ios/RNSScreenWindowTraits.h +1 -0
  66. package/ios/RNSScreenWindowTraits.m +20 -0
  67. package/ios/UIViewController+RNScreens.m +10 -0
  68. package/ios/utils/RNSUIBarButtonItem.h +5 -0
  69. package/ios/utils/RNSUIBarButtonItem.mm +22 -0
  70. package/lib/commonjs/fabric/Screen.js +27 -0
  71. package/lib/commonjs/fabric/Screen.js.map +1 -0
  72. package/lib/commonjs/fabric/ScreenNativeComponent.js +23 -0
  73. package/lib/commonjs/fabric/ScreenNativeComponent.js.map +1 -0
  74. package/lib/commonjs/fabric/ScreenStack.js +27 -0
  75. package/lib/commonjs/fabric/ScreenStack.js.map +1 -0
  76. package/lib/commonjs/fabric/ScreenStackHeaderConfigNativeComponent.js +27 -0
  77. package/lib/commonjs/fabric/ScreenStackHeaderConfigNativeComponent.js.map +1 -0
  78. package/lib/commonjs/fabric/ScreenStackHeaderSubview.js +34 -0
  79. package/lib/commonjs/fabric/ScreenStackHeaderSubview.js.map +1 -0
  80. package/lib/commonjs/fabric/ScreenStackHeaderSubviewNativeComponent.js +27 -0
  81. package/lib/commonjs/fabric/ScreenStackHeaderSubviewNativeComponent.js.map +1 -0
  82. package/lib/commonjs/fabric/ScreenStackNativeComponent.js +21 -0
  83. package/lib/commonjs/fabric/ScreenStackNativeComponent.js.map +1 -0
  84. package/lib/commonjs/fabric/index.js +40 -0
  85. package/lib/commonjs/fabric/index.js.map +1 -0
  86. package/lib/commonjs/index.native.js +32 -15
  87. package/lib/commonjs/index.native.js.map +1 -1
  88. package/lib/commonjs/native-stack/views/NativeStackView.js +33 -4
  89. package/lib/commonjs/native-stack/views/NativeStackView.js.map +1 -1
  90. package/lib/module/fabric/Screen.js +11 -0
  91. package/lib/module/fabric/Screen.js.map +1 -0
  92. package/lib/module/fabric/ScreenNativeComponent.js +11 -0
  93. package/lib/module/fabric/ScreenNativeComponent.js.map +1 -0
  94. package/lib/module/fabric/ScreenStack.js +12 -0
  95. package/lib/module/fabric/ScreenStack.js.map +1 -0
  96. package/lib/module/fabric/ScreenStackHeaderConfigNativeComponent.js +10 -0
  97. package/lib/module/fabric/ScreenStackHeaderConfigNativeComponent.js.map +1 -0
  98. package/lib/module/fabric/ScreenStackHeaderSubview.js +21 -0
  99. package/lib/module/fabric/ScreenStackHeaderSubview.js.map +1 -0
  100. package/lib/module/fabric/ScreenStackHeaderSubviewNativeComponent.js +10 -0
  101. package/lib/module/fabric/ScreenStackHeaderSubviewNativeComponent.js.map +1 -0
  102. package/lib/module/fabric/ScreenStackNativeComponent.js +9 -0
  103. package/lib/module/fabric/ScreenStackNativeComponent.js.map +1 -0
  104. package/lib/module/fabric/index.js +6 -0
  105. package/lib/module/fabric/index.js.map +1 -0
  106. package/lib/module/index.native.js +32 -15
  107. package/lib/module/index.native.js.map +1 -1
  108. package/lib/module/native-stack/views/NativeStackView.js +33 -4
  109. package/lib/module/native-stack/views/NativeStackView.js.map +1 -1
  110. package/lib/typescript/native-stack/types.d.ts +34 -0
  111. package/lib/typescript/reanimated/ReanimatedNativeStackScreen.d.ts +1 -1
  112. package/lib/typescript/reanimated/ReanimatedScreen.d.ts +1 -1
  113. package/lib/typescript/types.d.ts +60 -5
  114. package/native-stack/README.md +39 -3
  115. package/package.json +17 -3
  116. package/reanimated/package.json +6 -0
  117. package/src/fabric/Screen.js +12 -0
  118. package/src/fabric/ScreenNativeComponent.js +64 -0
  119. package/src/fabric/ScreenStack.js +8 -0
  120. package/src/fabric/ScreenStackHeaderConfigNativeComponent.js +54 -0
  121. package/src/fabric/ScreenStackHeaderSubview.js +20 -0
  122. package/src/fabric/ScreenStackHeaderSubviewNativeComponent.js +31 -0
  123. package/src/fabric/ScreenStackNativeComponent.js +19 -0
  124. package/src/fabric/index.js +11 -0
  125. package/src/index.native.tsx +35 -14
  126. package/src/native-stack/types.tsx +34 -0
  127. package/src/native-stack/views/NativeStackView.tsx +33 -4
  128. package/src/types.tsx +60 -5
@@ -0,0 +1,159 @@
1
+ #import "RNSScreenComponentView.h"
2
+ #import "RNSScreenStackHeaderConfigComponentView.h"
3
+
4
+ #import <React/RCTConversions.h>
5
+ #import <React/RCTMountingTransactionObserving.h>
6
+
7
+ #import <react/renderer/components/rnscreens/EventEmitters.h>
8
+ #import <react/renderer/components/rnscreens/Props.h>
9
+ #import <react/renderer/components/rnscreens/RCTComponentViewHelpers.h>
10
+ #import <rnscreens/RNSScreenComponentDescriptor.h>
11
+
12
+ #import "RCTFabricComponentsPlugins.h"
13
+
14
+ using namespace facebook::react;
15
+
16
+ @interface RNSScreenComponentView () <RCTRNSScreenViewProtocol, RCTMountingTransactionObserving>
17
+ @end
18
+
19
+ @implementation RNSScreenComponentView {
20
+ RNSScreenController *_controller;
21
+ RNSScreenShadowNode::ConcreteState::Shared _state;
22
+ }
23
+
24
+ - (instancetype)initWithFrame:(CGRect)frame
25
+ {
26
+ if (self = [super initWithFrame:frame]) {
27
+ static const auto defaultProps = std::make_shared<const RNSScreenProps>();
28
+ _props = defaultProps;
29
+ _controller = [[RNSScreenController alloc] initWithView:self];
30
+ }
31
+
32
+ return self;
33
+ }
34
+
35
+ - (void)mountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
36
+ {
37
+ [super mountChildComponentView:childComponentView index:index];
38
+ if ([childComponentView isKindOfClass:[RNSScreenStackHeaderConfigComponentView class]]) {
39
+ _config = childComponentView;
40
+ ((RNSScreenStackHeaderConfigComponentView *)childComponentView).screenView = self;
41
+ }
42
+ }
43
+
44
+ - (void)unmountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
45
+ {
46
+ [self.controller setViewToSnapshot];
47
+ if ([childComponentView isKindOfClass:[RNSScreenStackHeaderConfigComponentView class]]) {
48
+ _config = nil;
49
+ }
50
+ [super unmountChildComponentView:childComponentView index:index];
51
+ }
52
+
53
+ - (void)updateBounds
54
+ {
55
+ if (_state != nullptr) {
56
+ auto boundsSize = self.bounds.size;
57
+ auto newState = RNSScreenState{RCTSizeFromCGSize(boundsSize)};
58
+ _state->updateState(std::move(newState));
59
+ UINavigationController *navctr = _controller.navigationController;
60
+ [navctr.view setNeedsLayout];
61
+ }
62
+ }
63
+
64
+ - (UIView *)reactSuperview
65
+ {
66
+ return _reactSuperview;
67
+ }
68
+
69
+ - (void)notifyWillAppear
70
+ {
71
+ // If screen is already unmounted then there will be no event emitter
72
+ // it will be cleaned in prepareForRecycle
73
+ if (_eventEmitter != nullptr) {
74
+ std::dynamic_pointer_cast<const RNSScreenEventEmitter>(_eventEmitter)
75
+ ->onWillAppear(RNSScreenEventEmitter::OnWillAppear{});
76
+ }
77
+ }
78
+
79
+ - (void)notifyWillDisappear
80
+ {
81
+ // If screen is already unmounted then there will be no event emitter
82
+ // it will be cleaned in prepareForRecycle
83
+ if (_eventEmitter != nullptr) {
84
+ std::dynamic_pointer_cast<const RNSScreenEventEmitter>(_eventEmitter)
85
+ ->onWillDisappear(RNSScreenEventEmitter::OnWillDisappear{});
86
+ }
87
+ }
88
+
89
+ - (void)notifyAppear
90
+ {
91
+ // If screen is already unmounted then there will be no event emitter
92
+ // it will be cleaned in prepareForRecycle
93
+ if (_eventEmitter != nullptr) {
94
+ std::dynamic_pointer_cast<const RNSScreenEventEmitter>(_eventEmitter)->onAppear(RNSScreenEventEmitter::OnAppear{});
95
+ }
96
+ }
97
+
98
+ - (void)notifyDismissedWithCount:(int)dismissCount
99
+ {
100
+ // If screen is already unmounted then there will be no event emitter
101
+ // it will be cleaned in prepareForRecycle
102
+ if (_eventEmitter != nullptr) {
103
+ std::dynamic_pointer_cast<const RNSScreenEventEmitter>(_eventEmitter)
104
+ ->onDismissed(RNSScreenEventEmitter::OnDismissed{dismissCount : dismissCount});
105
+ }
106
+ }
107
+
108
+ - (void)notifyDisappear
109
+ {
110
+ // If screen is already unmounted then there will be no event emitter
111
+ // it will be cleaned in prepareForRecycle
112
+ if (_eventEmitter != nullptr) {
113
+ std::dynamic_pointer_cast<const RNSScreenEventEmitter>(_eventEmitter)
114
+ ->onDisappear(RNSScreenEventEmitter::OnDisappear{});
115
+ }
116
+ }
117
+
118
+ #pragma mark - RCTMountingTransactionObserving
119
+
120
+ - (void)mountingTransactionWillMountWithMetadata:(MountingTransactionMetadata const &)metadata
121
+ {
122
+ [self.controller takeSnapshot];
123
+ }
124
+
125
+ #pragma mark - RCTComponentViewProtocol
126
+
127
+ - (void)prepareForRecycle
128
+ {
129
+ [super prepareForRecycle];
130
+ // TODO: Make sure that there is no edge case when this should be uncommented
131
+ // _controller=nil;
132
+ _state.reset();
133
+ }
134
+
135
+ + (ComponentDescriptorProvider)componentDescriptorProvider
136
+ {
137
+ return concreteComponentDescriptorProvider<RNSScreenComponentDescriptor>();
138
+ }
139
+
140
+ - (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps
141
+ {
142
+ const auto &oldScreenProps = *std::static_pointer_cast<const RNSScreenProps>(_props);
143
+ const auto &newScreenProps = *std::static_pointer_cast<const RNSScreenProps>(props);
144
+
145
+ [super updateProps:props oldProps:oldProps];
146
+ }
147
+
148
+ - (void)updateState:(facebook::react::State::Shared const &)state
149
+ oldState:(facebook::react::State::Shared const &)oldState
150
+ {
151
+ _state = std::static_pointer_cast<const RNSScreenShadowNode::ConcreteState>(state);
152
+ }
153
+
154
+ @end
155
+
156
+ Class<RCTComponentViewProtocol> RNSScreenCls(void)
157
+ {
158
+ return RNSScreenComponentView.class;
159
+ }
@@ -23,6 +23,11 @@
23
23
  {
24
24
  return [self findActiveChildVC].supportedInterfaceOrientations;
25
25
  }
26
+
27
+ - (UIViewController *)childViewControllerForHomeIndicatorAutoHidden
28
+ {
29
+ return [self findActiveChildVC];
30
+ }
26
31
  #endif
27
32
 
28
33
  - (UIViewController *)findActiveChildVC
@@ -0,0 +1,10 @@
1
+ #import <UIKit/UIKit.h>
2
+
3
+ @interface RNSScreenController : UIViewController
4
+
5
+ - (instancetype)initWithView:(UIView *)view;
6
+ - (void)takeSnapshot;
7
+ - (void)setViewToSnapshot;
8
+ - (void)resetViewToScreen;
9
+
10
+ @end
@@ -0,0 +1,79 @@
1
+ #import <react/renderer/components/rnscreens/RCTComponentViewHelpers.h>
2
+ #import "RNSScreenComponentView.h"
3
+
4
+ @implementation RNSScreenController {
5
+ CGRect _lastViewFrame;
6
+ RNSScreenComponentView *_initialView;
7
+ UIView *_snapshot;
8
+ }
9
+
10
+ - (instancetype)initWithView:(UIView *)view
11
+ {
12
+ if (self = [super init]) {
13
+ self.view = view;
14
+ if ([view isKindOfClass:[RNSScreenComponentView class]]) {
15
+ _initialView = (RNSScreenComponentView *)view;
16
+ } else {
17
+ RCTLogError(@"ScreenController can only be initialized with ScreenComponentView");
18
+ }
19
+ }
20
+ return self;
21
+ }
22
+
23
+ - (void)takeSnapshot
24
+ {
25
+ _snapshot = [self.view snapshotViewAfterScreenUpdates:NO];
26
+ }
27
+
28
+ - (void)setViewToSnapshot
29
+ {
30
+ [self.view removeFromSuperview];
31
+ self.view = _snapshot;
32
+ }
33
+
34
+ - (void)resetViewToScreen
35
+ {
36
+ [self.view removeFromSuperview];
37
+ self.view = _initialView;
38
+ }
39
+
40
+ // TODO: Find out why this is executed when screen is going out
41
+ - (void)viewWillAppear:(BOOL)animated
42
+ {
43
+ [super viewWillAppear:animated];
44
+ [_initialView notifyWillAppear];
45
+ }
46
+
47
+ - (void)viewWillDisappear:(BOOL)animated
48
+ {
49
+ [super viewWillDisappear:animated];
50
+ [_initialView notifyWillDisappear];
51
+ }
52
+
53
+ - (void)viewDidAppear:(BOOL)animated
54
+ {
55
+ [super viewDidAppear:animated];
56
+ [_initialView notifyAppear];
57
+ }
58
+
59
+ - (void)viewDidDisappear:(BOOL)animated
60
+ {
61
+ [super viewDidDisappear:animated];
62
+ [_initialView notifyDisappear];
63
+ if (self.parentViewController == nil && self.presentingViewController == nil) {
64
+ // screen dismissed, send event
65
+ [_initialView notifyDismissedWithCount:1];
66
+ }
67
+ }
68
+
69
+ - (void)viewDidLayoutSubviews
70
+ {
71
+ [super viewDidLayoutSubviews];
72
+ BOOL isDisplayedWithinUINavController = [self.parentViewController isKindOfClass:[UINavigationController class]];
73
+ if (isDisplayedWithinUINavController && !CGRectEqualToRect(_lastViewFrame, self.view.frame)) {
74
+ _lastViewFrame = self.view.frame;
75
+ [_initialView updateBounds];
76
+ }
77
+ }
78
+
79
+ @end
@@ -45,6 +45,11 @@
45
45
  {
46
46
  return [self topViewController].supportedInterfaceOrientations;
47
47
  }
48
+
49
+ - (UIViewController *)childViewControllerForHomeIndicatorAutoHidden
50
+ {
51
+ return [self topViewController];
52
+ }
48
53
  #endif
49
54
 
50
55
  @end
@@ -645,13 +650,23 @@
645
650
 
646
651
  - (void)handleSwipe:(UIPanGestureRecognizer *)gestureRecognizer
647
652
  {
648
- float translation = [gestureRecognizer translationInView:gestureRecognizer.view].x;
649
- float velocity = [gestureRecognizer velocityInView:gestureRecognizer.view].x;
650
- float distance = gestureRecognizer.view.bounds.size.width;
651
- BOOL isRTL = _controller.view.semanticContentAttribute == UISemanticContentAttributeForceRightToLeft;
652
- if (isRTL) {
653
- translation = -translation;
654
- velocity = -velocity;
653
+ RNSScreenView *topScreen = (RNSScreenView *)_controller.viewControllers.lastObject.view;
654
+ float translation;
655
+ float velocity;
656
+ float distance;
657
+ if (topScreen.swipeDirection == RNSScreenSwipeDirectionVertical) {
658
+ translation = [gestureRecognizer translationInView:gestureRecognizer.view].y;
659
+ velocity = [gestureRecognizer velocityInView:gestureRecognizer.view].y;
660
+ distance = gestureRecognizer.view.bounds.size.height;
661
+ } else {
662
+ translation = [gestureRecognizer translationInView:gestureRecognizer.view].x;
663
+ velocity = [gestureRecognizer velocityInView:gestureRecognizer.view].x;
664
+ distance = gestureRecognizer.view.bounds.size.width;
665
+ BOOL isRTL = _controller.view.semanticContentAttribute == UISemanticContentAttributeForceRightToLeft;
666
+ if (isRTL) {
667
+ translation = -translation;
668
+ velocity = -velocity;
669
+ }
655
670
  }
656
671
 
657
672
  float transitionProgress = (translation / distance);
@@ -2,6 +2,13 @@
2
2
  #import "RNSScreen.h"
3
3
  #import "RNSScreenStack.h"
4
4
 
5
+ // proportions to default transition duration
6
+ static const float RNSSlideOpenTransitionDurationProportion = 1;
7
+ static const float RNSFadeOpenTransitionDurationProportion = 0.2 / 0.35;
8
+ static const float RNSSlideCloseTransitionDurationProportion = 0.25 / 0.35;
9
+ static const float RNSFadeCloseTransitionDurationProportion = 0.15 / 0.35;
10
+ static const float RNSFadeCloseDelayTransitionDurationProportion = 0.1 / 0.35;
11
+
5
12
  @implementation RNSScreenStackAnimator {
6
13
  UINavigationControllerOperation _operation;
7
14
  NSTimeInterval _transitionDuration;
@@ -11,7 +18,7 @@
11
18
  {
12
19
  if (self = [super init]) {
13
20
  _operation = operation;
14
- _transitionDuration = 0.35; // default duration
21
+ _transitionDuration = 0.35; // default duration in seconds
15
22
  }
16
23
  return self;
17
24
  }
@@ -32,6 +39,12 @@
32
39
  if (screen != nil && screen.stackAnimation == RNSScreenStackAnimationNone) {
33
40
  return 0;
34
41
  }
42
+
43
+ if (screen != nil && screen.transitionDuration != nil && [screen.transitionDuration floatValue] >= 0) {
44
+ float durationInSeconds = [screen.transitionDuration floatValue] / 1000.0;
45
+ return durationInSeconds;
46
+ }
47
+
35
48
  return _transitionDuration;
36
49
  }
37
50
 
@@ -184,14 +197,30 @@
184
197
  } else if (_operation == UINavigationControllerOperationPop) {
185
198
  toViewController.view.transform = CGAffineTransformIdentity;
186
199
  [[transitionContext containerView] insertSubview:toViewController.view belowSubview:fromViewController.view];
187
- [UIView animateWithDuration:[self transitionDuration:transitionContext]
188
- animations:^{
189
- toViewController.view.transform = CGAffineTransformIdentity;
190
- fromViewController.view.transform = topBottomTransform;
191
- }
192
- completion:^(BOOL finished) {
193
- [transitionContext completeTransition:![transitionContext transitionWasCancelled]];
194
- }];
200
+
201
+ void (^animationBlock)(void) = ^{
202
+ toViewController.view.transform = CGAffineTransformIdentity;
203
+ fromViewController.view.transform = topBottomTransform;
204
+ };
205
+ void (^completionBlock)(BOOL) = ^(BOOL finished) {
206
+ if (transitionContext.transitionWasCancelled) {
207
+ toViewController.view.transform = CGAffineTransformIdentity;
208
+ }
209
+ [transitionContext completeTransition:![transitionContext transitionWasCancelled]];
210
+ };
211
+
212
+ if (!transitionContext.isInteractive) {
213
+ [UIView animateWithDuration:[self transitionDuration:transitionContext]
214
+ animations:animationBlock
215
+ completion:completionBlock];
216
+ } else {
217
+ // we don't want the EaseInOut option when swiping to dismiss the view, it is the same in default animation option
218
+ [UIView animateWithDuration:[self transitionDuration:transitionContext]
219
+ delay:0.0
220
+ options:UIViewAnimationOptionCurveLinear
221
+ animations:animationBlock
222
+ completion:completionBlock];
223
+ }
195
224
  }
196
225
  }
197
226
 
@@ -202,6 +231,8 @@
202
231
  CGAffineTransform topBottomTransform =
203
232
  CGAffineTransformMakeTranslation(0, 0.08 * transitionContext.containerView.bounds.size.height);
204
233
 
234
+ const float transitionDuration = [self transitionDuration:transitionContext];
235
+
205
236
  if (_operation == UINavigationControllerOperationPush) {
206
237
  toViewController.view.transform = topBottomTransform;
207
238
  toViewController.view.alpha = 0.0;
@@ -209,7 +240,7 @@
209
240
 
210
241
  // Android Nougat open animation
211
242
  // http://aosp.opersys.com/xref/android-7.1.2_r37/xref/frameworks/base/core/res/res/anim/activity_open_enter.xml
212
- [UIView animateWithDuration:0.35
243
+ [UIView animateWithDuration:transitionDuration * RNSSlideOpenTransitionDurationProportion // defaults to 0.35 s
213
244
  delay:0
214
245
  options:UIViewAnimationOptionCurveEaseOut
215
246
  animations:^{
@@ -220,7 +251,7 @@
220
251
  fromViewController.view.transform = CGAffineTransformIdentity;
221
252
  [transitionContext completeTransition:![transitionContext transitionWasCancelled]];
222
253
  }];
223
- [UIView animateWithDuration:0.2
254
+ [UIView animateWithDuration:transitionDuration * RNSFadeOpenTransitionDurationProportion // defaults to 0.2 s
224
255
  delay:0
225
256
  options:UIViewAnimationOptionCurveEaseOut
226
257
  animations:^{
@@ -234,7 +265,7 @@
234
265
 
235
266
  // Android Nougat exit animation
236
267
  // http://aosp.opersys.com/xref/android-7.1.2_r37/xref/frameworks/base/core/res/res/anim/activity_close_exit.xml
237
- [UIView animateWithDuration:0.25
268
+ [UIView animateWithDuration:transitionDuration * RNSSlideCloseTransitionDurationProportion // defaults to 0.25 s
238
269
  delay:0
239
270
  options:UIViewAnimationOptionCurveEaseIn
240
271
  animations:^{
@@ -244,8 +275,8 @@
244
275
  completion:^(BOOL finished) {
245
276
  [transitionContext completeTransition:![transitionContext transitionWasCancelled]];
246
277
  }];
247
- [UIView animateWithDuration:0.15
248
- delay:0.1
278
+ [UIView animateWithDuration:transitionDuration * RNSFadeCloseTransitionDurationProportion // defaults to 0.15 s
279
+ delay:transitionDuration * RNSFadeCloseDelayTransitionDurationProportion // defaults to 0.1 s
249
280
  options:UIViewAnimationOptionCurveLinear
250
281
  animations:^{
251
282
  fromViewController.view.alpha = 0.0;
@@ -0,0 +1,15 @@
1
+ #import <UIKit/UIKit.h>
2
+
3
+ #import <React/RCTViewComponentView.h>
4
+
5
+ NS_ASSUME_NONNULL_BEGIN
6
+
7
+ @interface RNSScreenStackComponentView : RCTViewComponentView
8
+
9
+ @end
10
+
11
+ @interface RNSScreenStackView : UIView
12
+ - (instancetype)initWithComponentView:(RNSScreenStackComponentView *)component;
13
+ @end
14
+
15
+ NS_ASSUME_NONNULL_END