react-native-screens 3.12.0 → 3.14.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.
- package/README.md +2 -2
- package/RNScreens.podspec +5 -4
- package/android/build.gradle +18 -1
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt +8 -4
- package/android/src/main/java/com/swmansion/rnscreens/ScreenViewManager.kt +24 -6
- package/android/src/main/java/com/swmansion/rnscreens/ScreenWindowTraits.kt +18 -20
- package/android/src/main/jni/Android.mk +1 -2
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenManagerDelegate.java +39 -14
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenManagerInterface.java +15 -6
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackHeaderConfigManagerDelegate.java +3 -3
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackHeaderConfigManagerInterface.java +1 -1
- package/common/cpp/Android.mk +1 -2
- package/createNativeStackNavigator/README.md +4 -0
- package/ios/RNSConvert.h +30 -0
- package/ios/RNSConvert.mm +120 -0
- package/ios/RNSEnums.h +59 -0
- package/ios/RNSFullWindowOverlay.h +17 -2
- package/ios/RNSFullWindowOverlay.mm +199 -0
- package/ios/RNSScreen.h +70 -79
- package/ios/{RNSScreen.m → RNSScreen.mm} +679 -302
- package/ios/RNSScreenContainer.h +15 -1
- package/ios/{RNSScreenContainer.m → RNSScreenContainer.mm} +99 -8
- package/ios/{RNSScreenNavigationContainer.m → RNSScreenNavigationContainer.mm} +22 -0
- package/ios/RNSScreenStack.h +19 -3
- package/ios/{RNSScreenStack.m → RNSScreenStack.mm} +387 -124
- package/ios/{RNSScreenStackAnimator.m → RNSScreenStackAnimator.mm} +19 -14
- package/ios/RNSScreenStackHeaderConfig.h +20 -21
- package/ios/{RNSScreenStackHeaderConfig.m → RNSScreenStackHeaderConfig.mm} +232 -117
- package/ios/RNSScreenStackHeaderSubview.h +45 -0
- package/ios/RNSScreenStackHeaderSubview.mm +137 -0
- package/ios/RNSScreenViewEvent.h +12 -0
- package/ios/RNSScreenViewEvent.mm +59 -0
- package/ios/{RNSScreenWindowTraits.m → RNSScreenWindowTraits.mm} +3 -2
- package/ios/RNSSearchBar.h +14 -1
- package/ios/RNSSearchBar.mm +351 -0
- package/ios/{UIViewController+RNScreens.m → UIViewController+RNScreens.mm} +0 -0
- package/ios/{UIWindow+RNScreens.m → UIWindow+RNScreens.mm} +0 -0
- package/lib/commonjs/fabric/FullWindowOverlay.js +26 -0
- package/lib/commonjs/fabric/FullWindowOverlay.js.map +1 -0
- package/lib/commonjs/fabric/FullWindowOverlayNativeComponent.js +21 -0
- package/lib/commonjs/fabric/FullWindowOverlayNativeComponent.js.map +1 -0
- package/lib/commonjs/fabric/Screen.js +10 -8
- package/lib/commonjs/fabric/Screen.js.map +1 -1
- package/lib/commonjs/fabric/ScreenContainer.js +28 -0
- package/lib/commonjs/fabric/ScreenContainer.js.map +1 -0
- package/lib/commonjs/fabric/ScreenContainerNativeComponent.js +21 -0
- package/lib/commonjs/fabric/ScreenContainerNativeComponent.js.map +1 -0
- package/lib/commonjs/fabric/ScreenNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/ScreenNavigationContainer.js +28 -0
- package/lib/commonjs/fabric/ScreenNavigationContainer.js.map +1 -0
- package/lib/commonjs/fabric/ScreenNavigationContainerNativeComponent.js +21 -0
- package/lib/commonjs/fabric/ScreenNavigationContainerNativeComponent.js.map +1 -0
- package/lib/commonjs/fabric/ScreenStack.js +6 -7
- package/lib/commonjs/fabric/ScreenStack.js.map +1 -1
- package/lib/commonjs/fabric/ScreenStackHeaderConfigNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/ScreenStackHeaderSubview.js +4 -1
- package/lib/commonjs/fabric/ScreenStackHeaderSubview.js.map +1 -1
- package/lib/commonjs/fabric/ScreenStackNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/SearchBar.js +37 -0
- package/lib/commonjs/fabric/SearchBar.js.map +1 -0
- package/lib/commonjs/fabric/SearchBarNativeComponent.js +25 -0
- package/lib/commonjs/fabric/SearchBarNativeComponent.js.map +1 -0
- package/lib/commonjs/fabric/index.js +32 -0
- package/lib/commonjs/fabric/index.js.map +1 -1
- package/lib/commonjs/index.native.js +5 -18
- package/lib/commonjs/index.native.js.map +1 -1
- package/lib/commonjs/native-stack/views/NativeStackView.js +30 -0
- package/lib/commonjs/native-stack/views/NativeStackView.js.map +1 -1
- package/lib/commonjs/reanimated/ReanimatedNativeStackScreen.js +8 -2
- package/lib/commonjs/reanimated/ReanimatedNativeStackScreen.js.map +1 -1
- package/lib/module/fabric/FullWindowOverlay.js +15 -0
- package/lib/module/fabric/FullWindowOverlay.js.map +1 -0
- package/lib/module/fabric/FullWindowOverlayNativeComponent.js +9 -0
- package/lib/module/fabric/FullWindowOverlayNativeComponent.js.map +1 -0
- package/lib/module/fabric/Screen.js +8 -3
- package/lib/module/fabric/Screen.js.map +1 -1
- package/lib/module/fabric/ScreenContainer.js +17 -0
- package/lib/module/fabric/ScreenContainer.js.map +1 -0
- package/lib/module/fabric/ScreenContainerNativeComponent.js +9 -0
- package/lib/module/fabric/ScreenContainerNativeComponent.js.map +1 -0
- package/lib/module/fabric/ScreenNativeComponent.js.map +1 -1
- package/lib/module/fabric/ScreenNavigationContainer.js +17 -0
- package/lib/module/fabric/ScreenNavigationContainer.js.map +1 -0
- package/lib/module/fabric/ScreenNavigationContainerNativeComponent.js +9 -0
- package/lib/module/fabric/ScreenNavigationContainerNativeComponent.js.map +1 -0
- package/lib/module/fabric/ScreenStack.js +5 -2
- package/lib/module/fabric/ScreenStack.js.map +1 -1
- package/lib/module/fabric/ScreenStackHeaderConfigNativeComponent.js.map +1 -1
- package/lib/module/fabric/ScreenStackHeaderSubview.js +4 -1
- package/lib/module/fabric/ScreenStackHeaderSubview.js.map +1 -1
- package/lib/module/fabric/ScreenStackNativeComponent.js.map +1 -1
- package/lib/module/fabric/SearchBar.js +24 -0
- package/lib/module/fabric/SearchBar.js.map +1 -0
- package/lib/module/fabric/SearchBarNativeComponent.js +11 -0
- package/lib/module/fabric/SearchBarNativeComponent.js.map +1 -0
- package/lib/module/fabric/index.js +5 -1
- package/lib/module/fabric/index.js.map +1 -1
- package/lib/module/index.native.js +6 -20
- package/lib/module/index.native.js.map +1 -1
- package/lib/module/native-stack/views/NativeStackView.js +30 -0
- package/lib/module/native-stack/views/NativeStackView.js.map +1 -1
- package/lib/module/reanimated/ReanimatedNativeStackScreen.js +7 -2
- package/lib/module/reanimated/ReanimatedNativeStackScreen.js.map +1 -1
- package/lib/typescript/native-stack/types.d.ts +12 -0
- package/lib/typescript/reanimated/ReanimatedNativeStackScreen.d.ts +1 -1
- package/lib/typescript/reanimated/ReanimatedScreen.d.ts +1 -1
- package/lib/typescript/types.d.ts +24 -0
- package/native-stack/README.md +21 -0
- package/package.json +3 -4
- package/src/fabric/FullWindowOverlay.js +13 -0
- package/src/fabric/FullWindowOverlayNativeComponent.js +19 -0
- package/src/fabric/Screen.js +5 -2
- package/src/fabric/ScreenContainer.js +16 -0
- package/src/fabric/ScreenContainerNativeComponent.js +19 -0
- package/src/fabric/ScreenNativeComponent.js +41 -8
- package/src/fabric/ScreenNavigationContainer.js +16 -0
- package/src/fabric/ScreenNavigationContainerNativeComponent.js +19 -0
- package/src/fabric/ScreenStack.js +4 -2
- package/src/fabric/ScreenStackHeaderConfigNativeComponent.js +1 -1
- package/src/fabric/ScreenStackHeaderSubview.js +3 -1
- package/src/fabric/ScreenStackNativeComponent.js +4 -0
- package/src/fabric/SearchBar.js +20 -0
- package/src/fabric/SearchBarNativeComponent.js +62 -0
- package/src/fabric/index.js +8 -0
- package/src/index.native.tsx +13 -19
- package/src/native-stack/types.tsx +12 -0
- package/src/native-stack/views/NativeStackView.tsx +27 -0
- package/src/reanimated/ReanimatedNativeStackScreen.tsx +6 -0
- package/src/types.tsx +25 -0
- package/ios/RNSFullWindowOverlay.m +0 -105
- package/ios/RNSScreenComponentView.h +0 -23
- package/ios/RNSScreenComponentView.mm +0 -159
- package/ios/RNSScreenController.h +0 -10
- package/ios/RNSScreenController.mm +0 -79
- package/ios/RNSScreenStackComponentView.h +0 -15
- package/ios/RNSScreenStackComponentView.mm +0 -295
- package/ios/RNSScreenStackHeaderConfigComponentView.h +0 -42
- package/ios/RNSScreenStackHeaderConfigComponentView.mm +0 -662
- package/ios/RNSScreenStackHeaderSubviewComponentView.h +0 -14
- package/ios/RNSScreenStackHeaderSubviewComponentView.mm +0 -77
- package/ios/RNSSearchBar.m +0 -198
|
@@ -1,21 +1,39 @@
|
|
|
1
|
-
#
|
|
2
|
-
#import
|
|
3
|
-
#import
|
|
4
|
-
#import
|
|
5
|
-
#import
|
|
1
|
+
#ifdef RN_FABRIC_ENABLED
|
|
2
|
+
#import <React/RCTMountingTransactionObserving.h>
|
|
3
|
+
#import <React/RCTSurfaceTouchHandler.h>
|
|
4
|
+
#import <React/UIView+React.h>
|
|
5
|
+
#import <react/renderer/components/rnscreens/ComponentDescriptors.h>
|
|
6
|
+
#import <react/renderer/components/rnscreens/EventEmitters.h>
|
|
7
|
+
#import <react/renderer/components/rnscreens/Props.h>
|
|
8
|
+
#import <react/renderer/components/rnscreens/RCTComponentViewHelpers.h>
|
|
6
9
|
|
|
10
|
+
#import "RCTFabricComponentsPlugins.h"
|
|
11
|
+
|
|
12
|
+
#else
|
|
7
13
|
#import <React/RCTBridge.h>
|
|
8
14
|
#import <React/RCTRootContentView.h>
|
|
9
15
|
#import <React/RCTShadowView.h>
|
|
10
16
|
#import <React/RCTTouchHandler.h>
|
|
11
17
|
#import <React/RCTUIManager.h>
|
|
12
18
|
#import <React/RCTUIManagerUtils.h>
|
|
19
|
+
#endif // RN_FABRIC_ENABLED
|
|
20
|
+
|
|
21
|
+
#import "RNSScreen.h"
|
|
22
|
+
#import "RNSScreenStack.h"
|
|
23
|
+
#import "RNSScreenStackAnimator.h"
|
|
24
|
+
#import "RNSScreenStackHeaderConfig.h"
|
|
25
|
+
#import "RNSScreenWindowTraits.h"
|
|
13
26
|
|
|
14
27
|
@interface RNSScreenStackView () <
|
|
15
28
|
UINavigationControllerDelegate,
|
|
16
29
|
UIAdaptivePresentationControllerDelegate,
|
|
17
30
|
UIGestureRecognizerDelegate,
|
|
18
|
-
UIViewControllerTransitioningDelegate
|
|
31
|
+
UIViewControllerTransitioningDelegate
|
|
32
|
+
#ifdef RN_FABRIC_ENABLED
|
|
33
|
+
,
|
|
34
|
+
RCTMountingTransactionObserving
|
|
35
|
+
#endif
|
|
36
|
+
>
|
|
19
37
|
|
|
20
38
|
@property (nonatomic) NSMutableArray<UIViewController *> *presentedModals;
|
|
21
39
|
@property (nonatomic) BOOL updatingModals;
|
|
@@ -71,13 +89,29 @@
|
|
|
71
89
|
@implementation RNSScreenStackView {
|
|
72
90
|
UINavigationController *_controller;
|
|
73
91
|
NSMutableArray<RNSScreenView *> *_reactSubviews;
|
|
74
|
-
__weak RNSScreenStackManager *_manager;
|
|
75
|
-
BOOL _hasLayout;
|
|
76
92
|
BOOL _invalidated;
|
|
93
|
+
BOOL _isFullWidthSwiping;
|
|
77
94
|
UIPercentDrivenInteractiveTransition *_interactionController;
|
|
95
|
+
BOOL _hasLayout;
|
|
96
|
+
__weak RNSScreenStackManager *_manager;
|
|
78
97
|
BOOL _updateScheduled;
|
|
79
|
-
|
|
98
|
+
#ifdef RN_FABRIC_ENABLED
|
|
99
|
+
UIView *_snapshot;
|
|
100
|
+
#endif
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
#ifdef RN_FABRIC_ENABLED
|
|
104
|
+
- (instancetype)initWithFrame:(CGRect)frame
|
|
105
|
+
{
|
|
106
|
+
if (self = [super initWithFrame:frame]) {
|
|
107
|
+
static const auto defaultProps = std::make_shared<const facebook::react::RNSScreenStackProps>();
|
|
108
|
+
_props = defaultProps;
|
|
109
|
+
[self initCommonProps];
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return self;
|
|
80
113
|
}
|
|
114
|
+
#endif // RN_FABRIC_ENABLED
|
|
81
115
|
|
|
82
116
|
- (instancetype)initWithManager:(RNSScreenStackManager *)manager
|
|
83
117
|
{
|
|
@@ -85,26 +119,41 @@
|
|
|
85
119
|
_hasLayout = NO;
|
|
86
120
|
_invalidated = NO;
|
|
87
121
|
_manager = manager;
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
122
|
+
[self initCommonProps];
|
|
123
|
+
}
|
|
124
|
+
return self;
|
|
125
|
+
}
|
|
92
126
|
|
|
127
|
+
- (void)initCommonProps
|
|
128
|
+
{
|
|
129
|
+
_reactSubviews = [NSMutableArray new];
|
|
130
|
+
_presentedModals = [NSMutableArray new];
|
|
131
|
+
_controller = [RNScreensNavigationController new];
|
|
132
|
+
_controller.delegate = self;
|
|
93
133
|
#if !TARGET_OS_TV
|
|
94
|
-
|
|
134
|
+
[self setupGestureHandlers];
|
|
95
135
|
#endif
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
}
|
|
102
|
-
return self;
|
|
136
|
+
// we have to initialize viewControllers with a non empty array for
|
|
137
|
+
// largeTitle header to render in the opened state. If it is empty
|
|
138
|
+
// the header will render in collapsed state which is perhaps a bug
|
|
139
|
+
// in UIKit but ¯\_(ツ)_/¯
|
|
140
|
+
[_controller setViewControllers:@[ [UIViewController new] ]];
|
|
103
141
|
}
|
|
104
142
|
|
|
105
|
-
-
|
|
143
|
+
#pragma mark - Common
|
|
144
|
+
|
|
145
|
+
- (void)emitOnFinishTransitioningEvent
|
|
106
146
|
{
|
|
107
|
-
|
|
147
|
+
#ifdef RN_FABRIC_ENABLED
|
|
148
|
+
if (_eventEmitter != nullptr) {
|
|
149
|
+
std::dynamic_pointer_cast<const facebook::react::RNSScreenStackEventEmitter>(_eventEmitter)
|
|
150
|
+
->onFinishTransitioning(facebook::react::RNSScreenStackEventEmitter::OnFinishTransitioning{});
|
|
151
|
+
}
|
|
152
|
+
#else
|
|
153
|
+
if (self.onFinishTransitioning) {
|
|
154
|
+
self.onFinishTransitioning(nil);
|
|
155
|
+
}
|
|
156
|
+
#endif
|
|
108
157
|
}
|
|
109
158
|
|
|
110
159
|
- (void)navigationController:(UINavigationController *)navigationController
|
|
@@ -112,6 +161,12 @@
|
|
|
112
161
|
animated:(BOOL)animated
|
|
113
162
|
{
|
|
114
163
|
UIView *view = viewController.view;
|
|
164
|
+
#ifdef RN_FABRIC_ENABLED
|
|
165
|
+
if (![view isKindOfClass:[RNSScreenView class]]) {
|
|
166
|
+
// if the current view is a snapshot, config was already removed so we don't trigger the method
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
#endif
|
|
115
170
|
RNSScreenStackHeaderConfig *config = nil;
|
|
116
171
|
for (UIView *subview in view.reactSubviews) {
|
|
117
172
|
if ([subview isKindOfClass:[RNSScreenStackHeaderConfig class]]) {
|
|
@@ -122,96 +177,65 @@
|
|
|
122
177
|
[RNSScreenStackHeaderConfig willShowViewController:viewController animated:animated withConfig:config];
|
|
123
178
|
}
|
|
124
179
|
|
|
125
|
-
- (void)navigationController:(UINavigationController *)navigationController
|
|
126
|
-
didShowViewController:(UIViewController *)viewController
|
|
127
|
-
animated:(BOOL)animated
|
|
128
|
-
{
|
|
129
|
-
if (self.onFinishTransitioning) {
|
|
130
|
-
self.onFinishTransitioning(nil);
|
|
131
|
-
}
|
|
132
|
-
[RNSScreenWindowTraits updateWindowTraits];
|
|
133
|
-
}
|
|
134
|
-
|
|
135
180
|
- (void)presentationControllerDidDismiss:(UIPresentationController *)presentationController
|
|
136
181
|
{
|
|
137
182
|
// We don't directly set presentation delegate but instead rely on the ScreenView's delegate to
|
|
138
183
|
// forward certain calls to the container (Stack).
|
|
139
|
-
|
|
140
|
-
if ([screenView isKindOfClass:[RNSScreenView class]]) {
|
|
184
|
+
if ([presentationController.presentedViewController isKindOfClass:[RNSScreen class]]) {
|
|
141
185
|
// we trigger the update of status bar's appearance here because there is no other lifecycle method
|
|
142
186
|
// that can handle it when dismissing a modal, the same for orientation
|
|
143
187
|
[RNSScreenWindowTraits updateWindowTraits];
|
|
144
188
|
[_presentedModals removeObject:presentationController.presentedViewController];
|
|
189
|
+
|
|
190
|
+
_updatingModals = NO;
|
|
191
|
+
#ifdef RN_FABRIC_ENABLED
|
|
192
|
+
[self emitOnFinishTransitioningEvent];
|
|
193
|
+
#else
|
|
194
|
+
// we double check if there are no new controllers pending to be presented since someone could
|
|
195
|
+
// have tried to push another one during the transition.
|
|
196
|
+
// We don't do it on Fabric since update of container will be triggered from "unmount" method afterwards
|
|
197
|
+
[self updateContainer];
|
|
145
198
|
if (self.onFinishTransitioning) {
|
|
146
199
|
// instead of directly triggering onFinishTransitioning this time we enqueue the event on the
|
|
147
200
|
// main queue. We do that because onDismiss event is also enqueued and we want for the transition
|
|
148
201
|
// finish event to arrive later than onDismiss (see RNSScreen#notifyDismiss)
|
|
149
202
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
150
|
-
|
|
151
|
-
self.onFinishTransitioning(nil);
|
|
152
|
-
}
|
|
203
|
+
[self emitOnFinishTransitioningEvent];
|
|
153
204
|
});
|
|
154
205
|
}
|
|
206
|
+
#endif
|
|
155
207
|
}
|
|
156
208
|
}
|
|
157
209
|
|
|
158
|
-
- (void)markChildUpdated
|
|
159
|
-
{
|
|
160
|
-
// do nothing
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
- (void)didUpdateChildren
|
|
164
|
-
{
|
|
165
|
-
// do nothing
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
- (void)insertReactSubview:(RNSScreenView *)subview atIndex:(NSInteger)atIndex
|
|
169
|
-
{
|
|
170
|
-
if (![subview isKindOfClass:[RNSScreenView class]]) {
|
|
171
|
-
RCTLogError(@"ScreenStack only accepts children of type Screen");
|
|
172
|
-
return;
|
|
173
|
-
}
|
|
174
|
-
subview.reactSuperview = self;
|
|
175
|
-
[_reactSubviews insertObject:subview atIndex:atIndex];
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
- (void)removeReactSubview:(RNSScreenView *)subview
|
|
179
|
-
{
|
|
180
|
-
subview.reactSuperview = nil;
|
|
181
|
-
[_reactSubviews removeObject:subview];
|
|
182
|
-
}
|
|
183
|
-
|
|
184
210
|
- (NSArray<UIView *> *)reactSubviews
|
|
185
211
|
{
|
|
186
212
|
return _reactSubviews;
|
|
187
213
|
}
|
|
188
214
|
|
|
189
|
-
- (void)didUpdateReactSubviews
|
|
190
|
-
{
|
|
191
|
-
// we need to wait until children have their layout set. At this point they don't have the layout
|
|
192
|
-
// set yet, however the layout call is already enqueued on ui thread. Enqueuing update call on the
|
|
193
|
-
// ui queue will guarantee that the update will run after layout.
|
|
194
|
-
dispatch_async(dispatch_get_main_queue(), ^{
|
|
195
|
-
self->_hasLayout = YES;
|
|
196
|
-
[self maybeAddToParentAndUpdateContainer];
|
|
197
|
-
});
|
|
198
|
-
}
|
|
199
|
-
|
|
200
215
|
- (void)didMoveToWindow
|
|
201
216
|
{
|
|
202
217
|
[super didMoveToWindow];
|
|
218
|
+
#ifdef RN_FABRIC_ENABLED
|
|
219
|
+
// for handling nested stacks
|
|
220
|
+
[self maybeAddToParentAndUpdateContainer];
|
|
221
|
+
#else
|
|
203
222
|
if (!_invalidated) {
|
|
204
223
|
// We check whether the view has been invalidated before running side-effects in didMoveToWindow
|
|
205
224
|
// This is needed because when LayoutAnimations are used it is possible for view to be re-attached
|
|
206
225
|
// to a window despite the fact it has been removed from the React Native view hierarchy.
|
|
207
226
|
[self maybeAddToParentAndUpdateContainer];
|
|
208
227
|
}
|
|
228
|
+
#endif
|
|
209
229
|
}
|
|
210
230
|
|
|
211
231
|
- (void)maybeAddToParentAndUpdateContainer
|
|
212
232
|
{
|
|
213
233
|
BOOL wasScreenMounted = _controller.parentViewController != nil;
|
|
234
|
+
#ifdef RN_FABRIC_ENABLED
|
|
235
|
+
BOOL isScreenReadyForShowing = self.window;
|
|
236
|
+
#else
|
|
214
237
|
BOOL isScreenReadyForShowing = self.window && _hasLayout;
|
|
238
|
+
#endif
|
|
215
239
|
if (!isScreenReadyForShowing && !wasScreenMounted) {
|
|
216
240
|
// We wait with adding to parent controller until the stack is mounted and has its initial
|
|
217
241
|
// layout done.
|
|
@@ -314,9 +338,7 @@
|
|
|
314
338
|
__weak RNSScreenStackView *weakSelf = self;
|
|
315
339
|
|
|
316
340
|
void (^afterTransitions)(void) = ^{
|
|
317
|
-
|
|
318
|
-
weakSelf.onFinishTransitioning(nil);
|
|
319
|
-
}
|
|
341
|
+
[weakSelf emitOnFinishTransitioningEvent];
|
|
320
342
|
weakSelf.updatingModals = NO;
|
|
321
343
|
if (weakSelf.scheduleModalsUpdate) {
|
|
322
344
|
// if modals update was requested during setModalViewControllers we set scheduleModalsUpdate
|
|
@@ -360,7 +382,15 @@
|
|
|
360
382
|
#endif
|
|
361
383
|
|
|
362
384
|
BOOL shouldAnimate = lastModal && [next isKindOfClass:[RNSScreen class]] &&
|
|
363
|
-
((
|
|
385
|
+
((RNSScreen *)next).screenView.stackAnimation != RNSScreenStackAnimationNone;
|
|
386
|
+
|
|
387
|
+
// if you want to present another modal quick enough after dismissing the previous one,
|
|
388
|
+
// it will result in wrong changeRootController, see repro in
|
|
389
|
+
// https://github.com/software-mansion/react-native-screens/issues/1299 We call `updateContainer` again in
|
|
390
|
+
// `presentationControllerDidDismiss` to cover this case and present new controller
|
|
391
|
+
if (previous.beingDismissed) {
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
364
394
|
|
|
365
395
|
[previous presentViewController:next
|
|
366
396
|
animated:shouldAnimate
|
|
@@ -379,7 +409,7 @@
|
|
|
379
409
|
[_presentedModals containsObject:changeRootController.presentedViewController]) {
|
|
380
410
|
BOOL shouldAnimate = changeRootIndex == controllers.count &&
|
|
381
411
|
[changeRootController.presentedViewController isKindOfClass:[RNSScreen class]] &&
|
|
382
|
-
((
|
|
412
|
+
((RNSScreen *)changeRootController.presentedViewController).screenView.stackAnimation !=
|
|
383
413
|
RNSScreenStackAnimationNone;
|
|
384
414
|
[changeRootController dismissViewControllerAnimated:shouldAnimate completion:finish];
|
|
385
415
|
} else {
|
|
@@ -422,33 +452,39 @@
|
|
|
422
452
|
}
|
|
423
453
|
|
|
424
454
|
UIViewController *top = controllers.lastObject;
|
|
425
|
-
|
|
455
|
+
#ifdef RN_FABRIC_ENABLED
|
|
456
|
+
UIViewController *previousTop = _controller.topViewController;
|
|
457
|
+
#else
|
|
458
|
+
UIViewController *previousTop = _controller.viewControllers.lastObject;
|
|
459
|
+
#endif
|
|
426
460
|
|
|
427
|
-
//
|
|
461
|
+
// At the start we set viewControllers to contain a single UIViewController
|
|
428
462
|
// instance. This is a workaround for header height adjustment bug (see comment
|
|
429
463
|
// in the init function). Here, we need to detect if the initial empty
|
|
430
464
|
// controller is still there
|
|
431
|
-
BOOL firstTimePush = ![
|
|
465
|
+
BOOL firstTimePush = ![previousTop isKindOfClass:[RNSScreen class]];
|
|
432
466
|
|
|
433
467
|
if (firstTimePush) {
|
|
434
468
|
// nothing pushed yet
|
|
435
469
|
[_controller setViewControllers:controllers animated:NO];
|
|
436
|
-
} else if (top !=
|
|
437
|
-
|
|
438
|
-
// `stackAnimation: 'none'`, which will resolve in no animation anyways.
|
|
439
|
-
if (![controllers containsObject:lastTop]) {
|
|
470
|
+
} else if (top != previousTop) {
|
|
471
|
+
if (![controllers containsObject:previousTop]) {
|
|
440
472
|
// if the previous top screen does not exist anymore and the new top was not on the stack before, probably replace
|
|
441
473
|
// was called, so we check the animation
|
|
442
474
|
if (![_controller.viewControllers containsObject:top] &&
|
|
443
475
|
((RNSScreenView *)top.view).replaceAnimation == RNSScreenReplaceAnimationPush) {
|
|
444
476
|
// setting new controllers with animation does `push` animation by default
|
|
477
|
+
#ifdef RN_FABRIC_ENABLED
|
|
478
|
+
auto screenController = (RNSScreen *)top;
|
|
479
|
+
[screenController resetViewToScreen];
|
|
480
|
+
#endif
|
|
445
481
|
[_controller setViewControllers:controllers animated:YES];
|
|
446
482
|
} else {
|
|
447
483
|
// last top controller is no longer on stack
|
|
448
484
|
// in this case we set the controllers stack to the new list with
|
|
449
485
|
// added the last top element to it and perform (animated) pop
|
|
450
486
|
NSMutableArray *newControllers = [NSMutableArray arrayWithArray:controllers];
|
|
451
|
-
[newControllers addObject:
|
|
487
|
+
[newControllers addObject:previousTop];
|
|
452
488
|
[_controller setViewControllers:newControllers animated:NO];
|
|
453
489
|
[_controller popViewControllerAnimated:YES];
|
|
454
490
|
}
|
|
@@ -459,6 +495,10 @@
|
|
|
459
495
|
NSMutableArray *newControllers = [NSMutableArray arrayWithArray:controllers];
|
|
460
496
|
[newControllers removeLastObject];
|
|
461
497
|
[_controller setViewControllers:newControllers animated:NO];
|
|
498
|
+
#ifdef RN_FABRIC_ENABLED
|
|
499
|
+
auto screenController = (RNSScreen *)top;
|
|
500
|
+
[screenController resetViewToScreen];
|
|
501
|
+
#endif
|
|
462
502
|
[_controller pushViewController:top animated:YES];
|
|
463
503
|
} else {
|
|
464
504
|
// don't really know what this case could be, but may need to handle it
|
|
@@ -494,45 +534,23 @@
|
|
|
494
534
|
[self setModalViewControllers:modalControllers];
|
|
495
535
|
}
|
|
496
536
|
|
|
497
|
-
// By default, the header buttons that are not inside the native hit area
|
|
498
|
-
// cannot be clicked, so we check it by ourselves
|
|
499
|
-
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
|
|
500
|
-
{
|
|
501
|
-
if (CGRectContainsPoint(_controller.navigationBar.frame, point)) {
|
|
502
|
-
// headerConfig should be the first subview of the topmost screen
|
|
503
|
-
UIView *headerConfig = [[_reactSubviews.lastObject reactSubviews] firstObject];
|
|
504
|
-
if ([headerConfig isKindOfClass:[RNSScreenStackHeaderConfig class]]) {
|
|
505
|
-
UIView *headerHitTestResult = [headerConfig hitTest:point withEvent:event];
|
|
506
|
-
if (headerHitTestResult != nil) {
|
|
507
|
-
return headerHitTestResult;
|
|
508
|
-
}
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
|
-
return [super hitTest:point withEvent:event];
|
|
512
|
-
}
|
|
513
|
-
|
|
514
537
|
- (void)layoutSubviews
|
|
515
538
|
{
|
|
516
539
|
[super layoutSubviews];
|
|
517
540
|
_controller.view.frame = self.bounds;
|
|
518
541
|
}
|
|
519
542
|
|
|
520
|
-
- (void)invalidate
|
|
521
|
-
{
|
|
522
|
-
_invalidated = YES;
|
|
523
|
-
for (UIViewController *controller in _presentedModals) {
|
|
524
|
-
[controller dismissViewControllerAnimated:NO completion:nil];
|
|
525
|
-
}
|
|
526
|
-
[_presentedModals removeAllObjects];
|
|
527
|
-
[_controller willMoveToParentViewController:nil];
|
|
528
|
-
[_controller removeFromParentViewController];
|
|
529
|
-
}
|
|
530
|
-
|
|
531
543
|
- (void)dismissOnReload
|
|
532
544
|
{
|
|
545
|
+
#ifdef RN_FABRIC_ENABLED
|
|
546
|
+
if ([_controller.visibleViewController isKindOfClass:[RNSScreen class]]) {
|
|
547
|
+
[(RNSScreen *)_controller.visibleViewController resetViewToScreen];
|
|
548
|
+
}
|
|
549
|
+
#else
|
|
533
550
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
534
551
|
[self invalidate];
|
|
535
552
|
});
|
|
553
|
+
#endif
|
|
536
554
|
}
|
|
537
555
|
|
|
538
556
|
#pragma mark methods connected to transitioning
|
|
@@ -544,9 +562,9 @@
|
|
|
544
562
|
{
|
|
545
563
|
RNSScreenView *screen;
|
|
546
564
|
if (operation == UINavigationControllerOperationPush) {
|
|
547
|
-
screen = (
|
|
565
|
+
screen = ((RNSScreen *)toVC).screenView;
|
|
548
566
|
} else if (operation == UINavigationControllerOperationPop) {
|
|
549
|
-
screen = (
|
|
567
|
+
screen = ((RNSScreen *)fromVC).screenView;
|
|
550
568
|
}
|
|
551
569
|
if (screen != nil &&
|
|
552
570
|
// we need to return the animator when full width swiping even if the animation is not custom,
|
|
@@ -567,8 +585,13 @@
|
|
|
567
585
|
while (parent != nil && ![parent respondsToSelector:@selector(touchHandler)])
|
|
568
586
|
parent = parent.superview;
|
|
569
587
|
if (parent != nil) {
|
|
588
|
+
#ifdef RN_FABRIC_ENABLED
|
|
589
|
+
RCTSurfaceTouchHandler *touchHandler = [parent performSelector:@selector(touchHandler)];
|
|
590
|
+
#else
|
|
570
591
|
RCTTouchHandler *touchHandler = [parent performSelector:@selector(touchHandler)];
|
|
571
|
-
|
|
592
|
+
#endif
|
|
593
|
+
[touchHandler setEnabled:NO];
|
|
594
|
+
[touchHandler setEnabled:YES];
|
|
572
595
|
[touchHandler reset];
|
|
573
596
|
}
|
|
574
597
|
}
|
|
@@ -588,8 +611,9 @@
|
|
|
588
611
|
#else
|
|
589
612
|
if (topScreen.fullScreenSwipeEnabled) {
|
|
590
613
|
// we want only `RNSPanGestureRecognizer` to be able to recognize when
|
|
591
|
-
// `fullScreenSwipeEnabled` is set
|
|
592
|
-
if ([gestureRecognizer isKindOfClass:[RNSPanGestureRecognizer class]]
|
|
614
|
+
// `fullScreenSwipeEnabled` is set, and we are in the bounds set by user
|
|
615
|
+
if ([gestureRecognizer isKindOfClass:[RNSPanGestureRecognizer class]] &&
|
|
616
|
+
[self isInGestureResponseDistance:gestureRecognizer topScreen:topScreen]) {
|
|
593
617
|
_isFullWidthSwiping = YES;
|
|
594
618
|
[self cancelTouchesInParent];
|
|
595
619
|
return YES;
|
|
@@ -622,7 +646,8 @@
|
|
|
622
646
|
[self cancelTouchesInParent];
|
|
623
647
|
return YES;
|
|
624
648
|
}
|
|
625
|
-
|
|
649
|
+
|
|
650
|
+
#endif // TARGET_OS_TV
|
|
626
651
|
}
|
|
627
652
|
|
|
628
653
|
#if !TARGET_OS_TV
|
|
@@ -650,7 +675,7 @@
|
|
|
650
675
|
|
|
651
676
|
- (void)handleSwipe:(UIPanGestureRecognizer *)gestureRecognizer
|
|
652
677
|
{
|
|
653
|
-
RNSScreenView *topScreen = (
|
|
678
|
+
RNSScreenView *topScreen = ((RNSScreen *)_controller.viewControllers.lastObject).screenView;
|
|
654
679
|
float translation;
|
|
655
680
|
float velocity;
|
|
656
681
|
float distance;
|
|
@@ -704,7 +729,6 @@
|
|
|
704
729
|
}
|
|
705
730
|
}
|
|
706
731
|
}
|
|
707
|
-
#endif
|
|
708
732
|
|
|
709
733
|
- (id<UIViewControllerInteractiveTransitioning>)navigationController:(UINavigationController *)navigationController
|
|
710
734
|
interactionControllerForAnimationController:
|
|
@@ -719,8 +743,244 @@
|
|
|
719
743
|
return _interactionController;
|
|
720
744
|
}
|
|
721
745
|
|
|
746
|
+
- (void)navigationController:(UINavigationController *)navigationController
|
|
747
|
+
didShowViewController:(UIViewController *)viewController
|
|
748
|
+
animated:(BOOL)animated
|
|
749
|
+
{
|
|
750
|
+
[self emitOnFinishTransitioningEvent];
|
|
751
|
+
[RNSScreenWindowTraits updateWindowTraits];
|
|
752
|
+
}
|
|
753
|
+
#endif
|
|
754
|
+
|
|
755
|
+
- (void)markChildUpdated
|
|
756
|
+
{
|
|
757
|
+
// do nothing
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
- (void)didUpdateChildren
|
|
761
|
+
{
|
|
762
|
+
// do nothing
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
- (UIViewController *)reactViewController
|
|
766
|
+
{
|
|
767
|
+
return _controller;
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
- (BOOL)isInGestureResponseDistance:(UIGestureRecognizer *)gestureRecognizer topScreen:(RNSScreenView *)topScreen
|
|
771
|
+
{
|
|
772
|
+
NSDictionary *gestureResponseDistanceValues = topScreen.gestureResponseDistance;
|
|
773
|
+
float x = [gestureRecognizer locationInView:gestureRecognizer.view].x;
|
|
774
|
+
float y = [gestureRecognizer locationInView:gestureRecognizer.view].y;
|
|
775
|
+
BOOL isRTL = _controller.view.semanticContentAttribute == UISemanticContentAttributeForceRightToLeft;
|
|
776
|
+
if (isRTL) {
|
|
777
|
+
x = _controller.view.frame.size.width - x;
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
// see:
|
|
781
|
+
// https://github.com/software-mansion/react-native-screens/pull/1442/commits/74d4bae321875d8305ad021b3d448ebf713e7d56
|
|
782
|
+
// this prop is always default initialized so we do not expect any nils
|
|
783
|
+
float start = [gestureResponseDistanceValues[@"start"] floatValue];
|
|
784
|
+
float end = [gestureResponseDistanceValues[@"end"] floatValue];
|
|
785
|
+
float top = [gestureResponseDistanceValues[@"top"] floatValue];
|
|
786
|
+
float bottom = [gestureResponseDistanceValues[@"bottom"] floatValue];
|
|
787
|
+
|
|
788
|
+
// we check if any of the constraints are violated and return NO if so
|
|
789
|
+
return !(
|
|
790
|
+
(start != -1 && x < start) || (end != -1 && x > end) || (top != -1 && y < top) || (bottom != -1 && y > bottom));
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
// By default, the header buttons that are not inside the native hit area
|
|
794
|
+
// cannot be clicked, so we check it by ourselves
|
|
795
|
+
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
|
|
796
|
+
{
|
|
797
|
+
if (CGRectContainsPoint(_controller.navigationBar.frame, point)) {
|
|
798
|
+
// headerConfig should be the first subview of the topmost screen
|
|
799
|
+
UIView *headerConfig = [[_reactSubviews.lastObject reactSubviews] firstObject];
|
|
800
|
+
if ([headerConfig isKindOfClass:[RNSScreenStackHeaderConfig class]]) {
|
|
801
|
+
UIView *headerHitTestResult = [headerConfig hitTest:point withEvent:event];
|
|
802
|
+
if (headerHitTestResult != nil) {
|
|
803
|
+
return headerHitTestResult;
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
return [super hitTest:point withEvent:event];
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
- (BOOL)isScrollViewPanGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
|
|
811
|
+
{
|
|
812
|
+
// NOTE: This hack is required to restore native behavior of edge swipe (interactive pop gesture)
|
|
813
|
+
// without this, on a screen with a scroll view, it's only possible to pop view by panning horizontally
|
|
814
|
+
// if even slightly diagonal (or if in motion), scroll view will scroll, and edge swipe will be cancelled
|
|
815
|
+
if (![[gestureRecognizer view] isKindOfClass:[UIScrollView class]]) {
|
|
816
|
+
return NO;
|
|
817
|
+
}
|
|
818
|
+
UIScrollView *scrollView = (UIScrollView *)gestureRecognizer.view;
|
|
819
|
+
return scrollView.panGestureRecognizer == gestureRecognizer;
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
|
|
823
|
+
shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
|
|
824
|
+
{
|
|
825
|
+
return [self isScrollViewPanGestureRecognizer:otherGestureRecognizer];
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
|
|
829
|
+
shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
|
|
830
|
+
{
|
|
831
|
+
return [self isScrollViewPanGestureRecognizer:otherGestureRecognizer];
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
- (void)insertReactSubview:(RNSScreenView *)subview atIndex:(NSInteger)atIndex
|
|
835
|
+
{
|
|
836
|
+
if (![subview isKindOfClass:[RNSScreenView class]]) {
|
|
837
|
+
RCTLogError(@"ScreenStack only accepts children of type Screen");
|
|
838
|
+
return;
|
|
839
|
+
}
|
|
840
|
+
subview.reactSuperview = self;
|
|
841
|
+
[_reactSubviews insertObject:subview atIndex:atIndex];
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
- (void)removeReactSubview:(RNSScreenView *)subview
|
|
845
|
+
{
|
|
846
|
+
subview.reactSuperview = nil;
|
|
847
|
+
[_reactSubviews removeObject:subview];
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
- (void)didUpdateReactSubviews
|
|
851
|
+
{
|
|
852
|
+
// we need to wait until children have their layout set. At this point they don't have the layout
|
|
853
|
+
// set yet, however the layout call is already enqueued on ui thread. Enqueuing update call on the
|
|
854
|
+
// ui queue will guarantee that the update will run after layout.
|
|
855
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
856
|
+
self->_hasLayout = YES;
|
|
857
|
+
[self maybeAddToParentAndUpdateContainer];
|
|
858
|
+
});
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
#ifdef RN_FABRIC_ENABLED
|
|
862
|
+
#pragma mark - Fabric specific
|
|
863
|
+
|
|
864
|
+
- (void)mountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
|
|
865
|
+
{
|
|
866
|
+
if (![childComponentView isKindOfClass:[RNSScreenView class]]) {
|
|
867
|
+
RCTLogError(@"ScreenStack only accepts children of type Screen");
|
|
868
|
+
return;
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
RCTAssert(
|
|
872
|
+
childComponentView.reactSuperview == nil,
|
|
873
|
+
@"Attempt to mount already mounted component view. (parent: %@, child: %@, index: %@, existing parent: %@)",
|
|
874
|
+
self,
|
|
875
|
+
childComponentView,
|
|
876
|
+
@(index),
|
|
877
|
+
@([childComponentView.superview tag]));
|
|
878
|
+
|
|
879
|
+
[_reactSubviews insertObject:(RNSScreenView *)childComponentView atIndex:index];
|
|
880
|
+
((RNSScreenView *)childComponentView).reactSuperview = self;
|
|
881
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
882
|
+
[self maybeAddToParentAndUpdateContainer];
|
|
883
|
+
});
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
- (void)unmountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
|
|
887
|
+
{
|
|
888
|
+
RNSScreenView *screenChildComponent = (RNSScreenView *)childComponentView;
|
|
889
|
+
// We should only do a snapshot of a screen that is on the top.
|
|
890
|
+
// We also check `_presentedModals` since if you push 2 modals, second one is not a "child" of _controller.
|
|
891
|
+
// Also, when dissmised with a gesture, the screen already is not under the window, so we don't need to apply
|
|
892
|
+
// snapshot.
|
|
893
|
+
if (screenChildComponent.window != nil &&
|
|
894
|
+
((screenChildComponent == _controller.visibleViewController.view && _presentedModals.count < 2) ||
|
|
895
|
+
screenChildComponent == [_presentedModals.lastObject view])) {
|
|
896
|
+
[screenChildComponent.controller setViewToSnapshot:_snapshot];
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
RCTAssert(
|
|
900
|
+
screenChildComponent.reactSuperview == self,
|
|
901
|
+
@"Attempt to unmount a view which is mounted inside different view. (parent: %@, child: %@, index: %@)",
|
|
902
|
+
self,
|
|
903
|
+
screenChildComponent,
|
|
904
|
+
@(index));
|
|
905
|
+
RCTAssert(
|
|
906
|
+
(_reactSubviews.count > index) && [_reactSubviews objectAtIndex:index] == childComponentView,
|
|
907
|
+
@"Attempt to unmount a view which has a different index. (parent: %@, child: %@, index: %@, actual index: %@, tag at index: %@)",
|
|
908
|
+
self,
|
|
909
|
+
screenChildComponent,
|
|
910
|
+
@(index),
|
|
911
|
+
@([_reactSubviews indexOfObject:screenChildComponent]),
|
|
912
|
+
@([[_reactSubviews objectAtIndex:index] tag]));
|
|
913
|
+
screenChildComponent.reactSuperview = nil;
|
|
914
|
+
[_reactSubviews removeObject:screenChildComponent];
|
|
915
|
+
[screenChildComponent removeFromSuperview];
|
|
916
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
917
|
+
[self maybeAddToParentAndUpdateContainer];
|
|
918
|
+
});
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
- (void)takeSnapshot
|
|
922
|
+
{
|
|
923
|
+
_snapshot = [_controller.visibleViewController.view snapshotViewAfterScreenUpdates:NO];
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
- (void)mountingTransactionWillMount:(facebook::react::MountingTransaction const &)transaction
|
|
927
|
+
withSurfaceTelemetry:(facebook::react::SurfaceTelemetry const &)surfaceTelemetry
|
|
928
|
+
{
|
|
929
|
+
for (auto mutation : transaction.getMutations()) {
|
|
930
|
+
if (mutation.type == facebook::react::ShadowViewMutation::Type::Remove &&
|
|
931
|
+
mutation.parentShadowView.componentName != nil &&
|
|
932
|
+
strcmp(mutation.parentShadowView.componentName, "RNSScreenStack") == 0) {
|
|
933
|
+
[self takeSnapshot];
|
|
934
|
+
return;
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
- (void)prepareForRecycle
|
|
940
|
+
{
|
|
941
|
+
[super prepareForRecycle];
|
|
942
|
+
_reactSubviews = [NSMutableArray new];
|
|
943
|
+
|
|
944
|
+
for (UIViewController *controller in _presentedModals) {
|
|
945
|
+
[controller dismissViewControllerAnimated:NO completion:nil];
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
[_presentedModals removeAllObjects];
|
|
949
|
+
[self dismissOnReload];
|
|
950
|
+
[_controller willMoveToParentViewController:nil];
|
|
951
|
+
[_controller removeFromParentViewController];
|
|
952
|
+
[_controller setViewControllers:@[ [UIViewController new] ]];
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
+ (facebook::react::ComponentDescriptorProvider)componentDescriptorProvider
|
|
956
|
+
{
|
|
957
|
+
return facebook::react::concreteComponentDescriptorProvider<facebook::react::RNSScreenStackComponentDescriptor>();
|
|
958
|
+
}
|
|
959
|
+
#else
|
|
960
|
+
#pragma mark - Paper specific
|
|
961
|
+
|
|
962
|
+
- (void)invalidate
|
|
963
|
+
{
|
|
964
|
+
_invalidated = YES;
|
|
965
|
+
for (UIViewController *controller in _presentedModals) {
|
|
966
|
+
[controller dismissViewControllerAnimated:NO completion:nil];
|
|
967
|
+
}
|
|
968
|
+
[_presentedModals removeAllObjects];
|
|
969
|
+
[_controller willMoveToParentViewController:nil];
|
|
970
|
+
[_controller removeFromParentViewController];
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
#endif // RN_FABRIC_ENABLED
|
|
974
|
+
|
|
722
975
|
@end
|
|
723
976
|
|
|
977
|
+
#ifdef RN_FABRIC_ENABLED
|
|
978
|
+
Class<RCTComponentViewProtocol> RNSScreenStackCls(void)
|
|
979
|
+
{
|
|
980
|
+
return RNSScreenStackView.class;
|
|
981
|
+
}
|
|
982
|
+
#endif
|
|
983
|
+
|
|
724
984
|
@implementation RNSScreenStackManager {
|
|
725
985
|
NSPointerArray *_stacks;
|
|
726
986
|
}
|
|
@@ -729,6 +989,8 @@ RCT_EXPORT_MODULE()
|
|
|
729
989
|
|
|
730
990
|
RCT_EXPORT_VIEW_PROPERTY(onFinishTransitioning, RCTDirectEventBlock);
|
|
731
991
|
|
|
992
|
+
#ifdef RN_FABRIC_ENABLED
|
|
993
|
+
#else
|
|
732
994
|
- (UIView *)view
|
|
733
995
|
{
|
|
734
996
|
RNSScreenStackView *view = [[RNSScreenStackView alloc] initWithManager:self];
|
|
@@ -738,6 +1000,7 @@ RCT_EXPORT_VIEW_PROPERTY(onFinishTransitioning, RCTDirectEventBlock);
|
|
|
738
1000
|
[_stacks addPointer:(__bridge void *)view];
|
|
739
1001
|
return view;
|
|
740
1002
|
}
|
|
1003
|
+
#endif // RN_FABRIC_ENABLED
|
|
741
1004
|
|
|
742
1005
|
- (void)invalidate
|
|
743
1006
|
{
|