react-native-screens 4.0.0-beta.10 → 4.0.0-beta.12

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.
@@ -40,10 +40,17 @@ internal fun View.isInsideScrollViewWithRemoveClippedSubviews(): Boolean {
40
40
  }
41
41
  var parentView = this.parent
42
42
  while (parentView is ViewGroup && parentView !is ScreenStack) {
43
- if (parentView is ReactScrollView) {
44
- return parentView.removeClippedSubviews
43
+ when (parentView) {
44
+ is ReactHorizontalScrollView -> {
45
+ return parentView.removeClippedSubviews
46
+ }
47
+ is ReactScrollView -> {
48
+ return parentView.removeClippedSubviews
49
+ }
50
+ else -> {
51
+ parentView = parentView.parent
52
+ }
45
53
  }
46
- parentView = parentView.parent
47
54
  }
48
55
  return false
49
56
  }
package/ios/RNSEnums.h CHANGED
@@ -30,6 +30,7 @@ typedef NS_ENUM(NSInteger, RNSScreenSwipeDirection) {
30
30
  };
31
31
 
32
32
  typedef NS_ENUM(NSInteger, RNSActivityState) {
33
+ RNSActivityStateUndefined = -1,
33
34
  RNSActivityStateInactive = 0,
34
35
  RNSActivityStateTransitioningOrBelowTop = 1,
35
36
  RNSActivityStateOnTop = 2
package/ios/RNSScreen.h CHANGED
@@ -100,6 +100,8 @@ namespace react = facebook::react;
100
100
  @property (nonatomic) react::LayoutMetrics newLayoutMetrics;
101
101
  @property (weak, nonatomic) RNSScreenStackHeaderConfig *config;
102
102
  @property (nonatomic, readonly) BOOL hasHeaderConfig;
103
+ @property (nonatomic, readonly, getter=isMarkedForUnmountInCurrentTransaction)
104
+ BOOL markedForUnmountInCurrentTransaction;
103
105
  #else
104
106
  @property (nonatomic, copy) RCTDirectEventBlock onAppear;
105
107
  @property (nonatomic, copy) RCTDirectEventBlock onDisappear;
@@ -124,6 +126,10 @@ namespace react = facebook::react;
124
126
  - (void)updateBounds;
125
127
  - (void)notifyDismissedWithCount:(int)dismissCount;
126
128
  - (instancetype)initWithFrame:(CGRect)frame;
129
+ /// Tell `Screen` that it will be unmounted in next transaction.
130
+ /// The component needs this so that we can later decide whether to
131
+ /// replace it with snapshot or not.
132
+ - (void)willBeUnmountedInUpcomingTransaction;
127
133
  #else
128
134
  - (instancetype)initWithBridge:(RCTBridge *)bridge;
129
135
  #endif // RCT_NEW_ARCH_ENABLED
package/ios/RNSScreen.mm CHANGED
@@ -118,11 +118,15 @@ constexpr NSInteger SHEET_LARGEST_UNDIMMED_DETENT_NONE = -1;
118
118
  _hasStatusBarHiddenSet = NO;
119
119
  _hasOrientationSet = NO;
120
120
  _hasHomeIndicatorHiddenSet = NO;
121
+ _activityState = RNSActivityStateUndefined;
121
122
  #if !TARGET_OS_TV
122
123
  _sheetExpandsWhenScrolledToEdge = YES;
123
124
  #endif // !TARGET_OS_TV
124
125
  _sheetsScrollView = nil;
125
126
  _didSetSheetAllowedDetentsOnController = NO;
127
+ #ifdef RCT_NEW_ARCH_ENABLED
128
+ _markedForUnmountInCurrentTransaction = NO;
129
+ #endif // RCT_NEW_ARCH_ENABLED
126
130
  }
127
131
 
128
132
  - (UIViewController *)reactViewController
@@ -304,15 +308,25 @@ constexpr NSInteger SHEET_LARGEST_UNDIMMED_DETENT_NONE = -1;
304
308
  {
305
309
  int activityState = [activityStateOrNil intValue];
306
310
  if (activityStateOrNil != nil && activityState != -1 && activityState != _activityState) {
307
- if ([_controller.navigationController isKindOfClass:RNSNavigationController.class] &&
308
- _activityState < activityState) {
309
- RCTLogError(@"[RNScreens] activityState can only progress in NativeStack");
310
- }
311
+ [self maybeAssertActivityStateProgressionOldValue:_activityState newValue:activityState];
311
312
  _activityState = activityState;
312
313
  [_reactSuperview markChildUpdated];
313
314
  }
314
315
  }
315
316
 
317
+ - (void)maybeAssertActivityStateProgressionOldValue:(int)oldValue newValue:(int)newValue
318
+ {
319
+ if (self.isNativeStackScreen && newValue < oldValue) {
320
+ RCTLogError(@"[RNScreens] activityState can only progress in NativeStack");
321
+ }
322
+ }
323
+
324
+ /// Note that this method works only after the screen is actually mounted under a screen stack view.
325
+ - (BOOL)isNativeStackScreen
326
+ {
327
+ return [_reactSuperview isKindOfClass:RNSScreenStackView.class];
328
+ }
329
+
316
330
  #if !TARGET_OS_TV && !TARGET_OS_VISION
317
331
  - (void)setStatusBarStyle:(RNSStatusBarStyle)statusBarStyle
318
332
  {
@@ -1082,6 +1096,11 @@ constexpr NSInteger SHEET_LARGEST_UNDIMMED_DETENT_NONE = -1;
1082
1096
  return _config != nil;
1083
1097
  }
1084
1098
 
1099
+ - (void)willBeUnmountedInUpcomingTransaction
1100
+ {
1101
+ _markedForUnmountInCurrentTransaction = YES;
1102
+ }
1103
+
1085
1104
  + (react::ComponentDescriptorProvider)componentDescriptorProvider
1086
1105
  {
1087
1106
  return react::concreteComponentDescriptorProvider<react::RNSScreenComponentDescriptor>();
@@ -953,7 +953,7 @@ namespace react = facebook::react;
953
953
 
954
954
  - (void)markChildUpdated
955
955
  {
956
- // do nothing
956
+ // In native stack this should be called only for `preload` purposes.
957
957
  [self updateContainer];
958
958
  }
959
959
 
@@ -1208,6 +1208,7 @@ namespace react = facebook::react;
1208
1208
  if (mutation.type == react::ShadowViewMutation::Delete) {
1209
1209
  RNSScreenView *_Nullable toBeRemovedChild = [self childScreenForTag:mutation.oldChildShadowView.tag];
1210
1210
  if (toBeRemovedChild != nil) {
1211
+ [toBeRemovedChild willBeUnmountedInUpcomingTransaction];
1211
1212
  _toBeDeletedScreens.push_back(toBeRemovedChild);
1212
1213
  }
1213
1214
  }
@@ -823,12 +823,17 @@ namespace react = facebook::react;
823
823
 
824
824
  - (void)unmountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
825
825
  {
826
- // For explanation of why we can make a snapshot here despite the fact that our children are already
827
- // unmounted see https://github.com/software-mansion/react-native-screens/pull/2261
828
- [self replaceNavigationBarViewsWithSnapshotOfSubview:(RNSScreenStackHeaderSubview *)childComponentView];
826
+ BOOL isGoingToBeRemoved = _screenView.isMarkedForUnmountInCurrentTransaction;
827
+ if (isGoingToBeRemoved) {
828
+ // For explanation of why we can make a snapshot here despite the fact that our children are already
829
+ // unmounted see https://github.com/software-mansion/react-native-screens/pull/2261
830
+ [self replaceNavigationBarViewsWithSnapshotOfSubview:(RNSScreenStackHeaderSubview *)childComponentView];
831
+ }
829
832
  [_reactSubviews removeObject:(RNSScreenStackHeaderSubview *)childComponentView];
830
833
  [childComponentView removeFromSuperview];
831
- [self updateViewControllerIfNeeded];
834
+ if (!isGoingToBeRemoved) {
835
+ [self updateViewControllerIfNeeded];
836
+ }
832
837
  }
833
838
 
834
839
  - (void)replaceNavigationBarViewsWithSnapshotOfSubview:(RNSScreenStackHeaderSubview *)childComponentView
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-screens",
3
- "version": "4.0.0-beta.10",
3
+ "version": "4.0.0-beta.12",
4
4
  "description": "Native navigation primitives for your React Native app.",
5
5
  "scripts": {
6
6
  "submodules": "git submodule update --init --recursive && (cd react-navigation && yarn)",