react-native-screens 4.0.0 → 4.2.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 (48) hide show
  1. package/android/src/main/cpp/jni-adapter.cpp +3 -0
  2. package/android/src/main/java/com/swmansion/rnscreens/InsetsObserverProxy.kt +5 -6
  3. package/android/src/main/java/com/swmansion/rnscreens/Screen.kt +8 -6
  4. package/android/src/main/java/com/swmansion/rnscreens/ScreenFooter.kt +16 -4
  5. package/android/src/main/java/com/swmansion/rnscreens/ScreenWindowTraits.kt +0 -1
  6. package/android/src/main/java/com/swmansion/rnscreens/ext/ViewExt.kt +0 -24
  7. package/common/cpp/react/renderer/components/rnscreens/RNSScreenComponentDescriptor.h +1 -1
  8. package/common/cpp/react/renderer/components/rnscreens/RNSScreenShadowNode.cpp +1 -1
  9. package/common/cpp/react/renderer/components/rnscreens/RNSScreenStackHeaderConfigComponentDescriptor.h +5 -0
  10. package/common/cpp/react/renderer/components/rnscreens/RNSScreenStackHeaderConfigShadowNode.cpp +14 -0
  11. package/common/cpp/react/renderer/components/rnscreens/RNSScreenStackHeaderConfigShadowNode.h +8 -0
  12. package/common/cpp/react/renderer/components/rnscreens/RNSScreenStackHeaderConfigState.cpp +12 -1
  13. package/common/cpp/react/renderer/components/rnscreens/RNSScreenStackHeaderConfigState.h +9 -2
  14. package/common/cpp/react/renderer/components/rnscreens/RNSScreenStackHeaderSubviewComponentDescriptor.h +1 -1
  15. package/common/cpp/react/renderer/components/rnscreens/RNSScreenStackHeaderSubviewShadowNode.cpp +1 -1
  16. package/common/cpp/react/renderer/components/rnscreens/RNSScreenStackHeaderSubviewShadowNode.h +0 -1
  17. package/common/cpp/react/renderer/components/rnscreens/RNSScreenStackHeaderSubviewState.cpp +1 -1
  18. package/common/cpp/react/renderer/components/rnscreens/RNSScreenStackHeaderSubviewState.h +1 -2
  19. package/common/cpp/react/renderer/components/rnscreens/RNSScreenState.cpp +1 -1
  20. package/common/cpp/react/renderer/components/rnscreens/RNSScreenState.h +2 -2
  21. package/ios/RNSConvert.h +0 -2
  22. package/ios/RNSConvert.mm +82 -68
  23. package/ios/RNSFullWindowOverlay.mm +4 -0
  24. package/ios/RNSScreen.mm +5 -0
  25. package/ios/RNSScreenContainer.mm +5 -0
  26. package/ios/RNSScreenFooter.mm +24 -25
  27. package/ios/RNSScreenStack.mm +9 -11
  28. package/ios/RNSScreenStackHeaderConfig.h +9 -6
  29. package/ios/RNSScreenStackHeaderConfig.mm +70 -29
  30. package/ios/RNSScreenStackHeaderSubview.h +0 -7
  31. package/ios/RNSScreenStackHeaderSubview.mm +6 -24
  32. package/ios/events/RNSHeaderHeightChangeEvent.h +0 -1
  33. package/ios/events/RNSScreenViewEvent.h +0 -1
  34. package/ios/utils/RNSDefines.h +7 -0
  35. package/lib/commonjs/components/ScreenFooter.js +9 -0
  36. package/lib/commonjs/components/ScreenFooter.js.map +1 -1
  37. package/lib/commonjs/components/ScreenStackItem.js +4 -1
  38. package/lib/commonjs/components/ScreenStackItem.js.map +1 -1
  39. package/lib/module/components/ScreenFooter.js +8 -0
  40. package/lib/module/components/ScreenFooter.js.map +1 -1
  41. package/lib/module/components/ScreenStackItem.js +4 -1
  42. package/lib/module/components/ScreenStackItem.js.map +1 -1
  43. package/lib/typescript/components/ScreenFooter.d.ts +4 -0
  44. package/lib/typescript/components/ScreenFooter.d.ts.map +1 -1
  45. package/lib/typescript/components/ScreenStackItem.d.ts.map +1 -1
  46. package/package.json +1 -1
  47. package/src/components/ScreenFooter.tsx +8 -0
  48. package/src/components/ScreenStackItem.tsx +7 -0
@@ -1,5 +1,6 @@
1
1
  #import <UIKit/UIKit.h>
2
2
 
3
+ #import "RNSDefines.h"
3
4
  #import "RNSFullWindowOverlay.h"
4
5
 
5
6
  #ifdef RCT_NEW_ARCH_ENABLED
@@ -198,6 +199,8 @@
198
199
  [childComponentView removeFromSuperview];
199
200
  }
200
201
 
202
+ RNS_IGNORE_SUPER_CALL_BEGIN
203
+ // We do not set frame for ouselves, but rather for the container.
201
204
  - (void)updateLayoutMetrics:(react::LayoutMetrics const &)layoutMetrics
202
205
  oldLayoutMetrics:(react::LayoutMetrics const &)oldLayoutMetrics
203
206
  {
@@ -205,6 +208,7 @@
205
208
  _reactFrame = frame;
206
209
  [_container setFrame:frame];
207
210
  }
211
+ RNS_IGNORE_SUPER_CALL_END
208
212
 
209
213
  #else
210
214
  #pragma mark - Paper specific
package/ios/RNSScreen.mm CHANGED
@@ -31,6 +31,7 @@
31
31
  #import "RNSScreenStack.h"
32
32
  #import "RNSScreenStackHeaderConfig.h"
33
33
 
34
+ #import "RNSDefines.h"
34
35
  #import "UIView+RNSUtility.h"
35
36
 
36
37
  #ifdef RCT_NEW_ARCH_ENABLED
@@ -136,10 +137,12 @@ constexpr NSInteger SHEET_LARGEST_UNDIMMED_DETENT_NONE = -1;
136
137
  }
137
138
 
138
139
  #ifdef RCT_NEW_ARCH_ENABLED
140
+ RNS_IGNORE_SUPER_CALL_BEGIN
139
141
  - (NSArray<UIView *> *)reactSubviews
140
142
  {
141
143
  return _reactSubviews;
142
144
  }
145
+ RNS_IGNORE_SUPER_CALL_END
143
146
  #endif
144
147
 
145
148
  - (void)updateBounds
@@ -374,10 +377,12 @@ constexpr NSInteger SHEET_LARGEST_UNDIMMED_DETENT_NONE = -1;
374
377
  }
375
378
  #endif
376
379
 
380
+ RNS_IGNORE_SUPER_CALL_BEGIN
377
381
  - (UIView *)reactSuperview
378
382
  {
379
383
  return _reactSuperview;
380
384
  }
385
+ RNS_IGNORE_SUPER_CALL_END
381
386
 
382
387
  /// This is RNSScreenContentWrapperDelegate method, where we do get notified when React did update frame of our child.
383
388
  - (void)reactDidSetFrame:(CGRect)reactFrame forContentWrapper:(RNSScreenContentWrapper *)contentWrapepr
@@ -1,4 +1,5 @@
1
1
  #import "RNSScreenContainer.h"
2
+ #import "RNSDefines.h"
2
3
  #import "RNSScreen.h"
3
4
 
4
5
  #ifdef RCT_NEW_ARCH_ENABLED
@@ -89,6 +90,9 @@ namespace react = facebook::react;
89
90
  [self updateContainer];
90
91
  }
91
92
 
93
+ RNS_IGNORE_SUPER_CALL_BEGIN
94
+ // We do not call super as we do not want to update UIKit model. It will
95
+ // be updated after we receive all mutations.
92
96
  - (void)insertReactSubview:(RNSScreenView *)subview atIndex:(NSInteger)atIndex
93
97
  {
94
98
  subview.reactSuperview = self;
@@ -106,6 +110,7 @@ namespace react = facebook::react;
106
110
  {
107
111
  return _reactSubviews;
108
112
  }
113
+ RNS_IGNORE_SUPER_CALL_END
109
114
 
110
115
  - (UIViewController *)reactViewController
111
116
  {
@@ -26,35 +26,34 @@
26
26
  - (void)willMoveToSuperview:(UIView *)newSuperview
27
27
  {
28
28
  [super willMoveToSuperview:newSuperview];
29
- if ([newSuperview isKindOfClass:RNSScreenView.class]) {
30
- RNSScreenView *screen = (RNSScreenView *)newSuperview;
31
- _parent = (RNSScreenView *)newSuperview;
32
-
33
- // [NSLayoutConstraint activateConstraints:@[
34
- // [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeBottom
35
- // relatedBy:NSLayoutRelationEqual toItem:screen attribute:NSLayoutAttributeBottom multiplier:1.0
36
- // constant:0.0], [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeLeft
37
- // relatedBy:NSLayoutRelationEqual toItem:screen attribute:NSLayoutAttributeLeft multiplier:1.0 constant:0.0],
38
- // [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual
39
- // toItem:screen attribute:NSLayoutAttributeRight multiplier:1.0 constant:0.0], [NSLayoutConstraint
40
- // constraintWithItem:self attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:screen
41
- // attribute:NSLayoutAttributeTop multiplier:1.0 constant:0.0], [NSLayoutConstraint constraintWithItem:screen
42
- // attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self
43
- // attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0.0], [NSLayoutConstraint
44
- // constraintWithItem:screen attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self
45
- // attribute:NSLayoutAttributeLeft multiplier:1.0 constant:0.0], [NSLayoutConstraint constraintWithItem:screen
46
- // attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self
47
- // attribute:NSLayoutAttributeRight multiplier:1.0 constant:0.0], [NSLayoutConstraint constraintWithItem:screen
48
- // attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeTop
49
- // multiplier:1.0 constant:0.0],
50
- // ]];
51
- // [self setNeedsLayout];
52
- }
29
+ // if ([newSuperview isKindOfClass:RNSScreenView.class]) {
30
+ // RNSScreenView *screen = (RNSScreenView *)newSuperview;
31
+ // _parent = (RNSScreenView *)newSuperview;
32
+
33
+ // [NSLayoutConstraint activateConstraints:@[
34
+ // [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeBottom
35
+ // relatedBy:NSLayoutRelationEqual toItem:screen attribute:NSLayoutAttributeBottom multiplier:1.0
36
+ // constant:0.0], [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeLeft
37
+ // relatedBy:NSLayoutRelationEqual toItem:screen attribute:NSLayoutAttributeLeft multiplier:1.0 constant:0.0],
38
+ // [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual
39
+ // toItem:screen attribute:NSLayoutAttributeRight multiplier:1.0 constant:0.0], [NSLayoutConstraint
40
+ // constraintWithItem:self attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:screen
41
+ // attribute:NSLayoutAttributeTop multiplier:1.0 constant:0.0], [NSLayoutConstraint constraintWithItem:screen
42
+ // attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self
43
+ // attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0.0], [NSLayoutConstraint
44
+ // constraintWithItem:screen attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self
45
+ // attribute:NSLayoutAttributeLeft multiplier:1.0 constant:0.0], [NSLayoutConstraint constraintWithItem:screen
46
+ // attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self
47
+ // attribute:NSLayoutAttributeRight multiplier:1.0 constant:0.0], [NSLayoutConstraint constraintWithItem:screen
48
+ // attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeTop
49
+ // multiplier:1.0 constant:0.0],
50
+ // ]];
51
+ // [self setNeedsLayout];
52
+ // }
53
53
  }
54
54
 
55
55
  - (void)didMoveToSuperview
56
56
  {
57
- NSLog(@"Adding constraints between %@ and %@", self, _parent);
58
57
  if (_parent != nil) {
59
58
  // [NSLayoutConstraint activateConstraints:@[
60
59
  // [NSLayoutConstraint constraintWithItem:self
@@ -20,6 +20,7 @@
20
20
  #import "RCTTouchHandler+RNSUtility.h"
21
21
  #endif // RCT_NEW_ARCH_ENABLED
22
22
 
23
+ #import "RNSDefines.h"
23
24
  #import "RNSPercentDrivenInteractiveTransition.h"
24
25
  #import "RNSScreen.h"
25
26
  #import "RNSScreenStack.h"
@@ -290,10 +291,12 @@ namespace react = facebook::react;
290
291
  }
291
292
  }
292
293
 
294
+ RNS_IGNORE_SUPER_CALL_BEGIN
293
295
  - (NSArray<UIView *> *)reactSubviews
294
296
  {
295
297
  return _reactSubviews;
296
298
  }
299
+ RNS_IGNORE_SUPER_CALL_END
297
300
 
298
301
  - (void)didMoveToWindow
299
302
  {
@@ -1086,6 +1089,9 @@ namespace react = facebook::react;
1086
1089
 
1087
1090
  #endif // !TARGET_OS_TV
1088
1091
 
1092
+ RNS_IGNORE_SUPER_CALL_BEGIN
1093
+ // We hijack the udpates as we don't want to update UIKit model yet.
1094
+ // This is done after all mutations are processed.
1089
1095
  - (void)insertReactSubview:(RNSScreenView *)subview atIndex:(NSInteger)atIndex
1090
1096
  {
1091
1097
  if (![subview isKindOfClass:[RNSScreenView class]]) {
@@ -1101,6 +1107,7 @@ namespace react = facebook::react;
1101
1107
  subview.reactSuperview = nil;
1102
1108
  [_reactSubviews removeObject:subview];
1103
1109
  }
1110
+ RNS_IGNORE_SUPER_CALL_END
1104
1111
 
1105
1112
  - (void)didUpdateReactSubviews
1106
1113
  {
@@ -1176,16 +1183,7 @@ namespace react = facebook::react;
1176
1183
  - (void)unmountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
1177
1184
  {
1178
1185
  RNSScreenView *screenChildComponent = (RNSScreenView *)childComponentView;
1179
-
1180
- // We should only do a snapshot of a screen that is on the top.
1181
- // We also check `_presentedModals` since if you push 2 modals, second one is not a "child" of _controller.
1182
- // Also, when dissmised with a gesture, the screen already is not under the window, so we don't need to apply
1183
- // snapshot.
1184
- if (screenChildComponent.window != nil &&
1185
- ((screenChildComponent == _controller.visibleViewController.view && _presentedModals.count < 2) ||
1186
- screenChildComponent == [_presentedModals.lastObject view])) {
1187
- [screenChildComponent.controller setViewToSnapshot];
1188
- }
1186
+ [screenChildComponent.controller setViewToSnapshot];
1189
1187
 
1190
1188
  RCTAssert(
1191
1189
  screenChildComponent.reactSuperview == self,
@@ -1288,7 +1286,7 @@ namespace react = facebook::react;
1288
1286
  // with modal presentation or foreign modal presented from inside a Screen.
1289
1287
  - (void)dismissAllRelatedModals
1290
1288
  {
1291
- [_controller dismissViewControllerAnimated:NO completion:nil];
1289
+ [_controller dismissViewControllerAnimated:YES completion:nil];
1292
1290
 
1293
1291
  // This loop seems to be excessive. Above message send to `_controller` should
1294
1292
  // be enough, because system dismisses the controllers recursively,
@@ -12,7 +12,7 @@
12
12
 
13
13
  @interface NSString (RNSStringUtil)
14
14
 
15
- + (BOOL)RNSisBlank:(NSString *)string;
15
+ + (BOOL)RNSisBlank:(nullable NSString *)string;
16
16
 
17
17
  @end
18
18
 
@@ -31,6 +31,8 @@
31
31
  @property (nonatomic) BOOL hide;
32
32
  #endif
33
33
 
34
+ NS_ASSUME_NONNULL_BEGIN
35
+
34
36
  @property (nonatomic, retain) NSString *title;
35
37
  @property (nonatomic, retain) NSString *titleFontFamily;
36
38
  @property (nonatomic, retain) NSNumber *titleFontSize;
@@ -58,9 +60,11 @@
58
60
  @property (nonatomic) UINavigationItemBackButtonDisplayMode backButtonDisplayMode;
59
61
  @property (nonatomic) RNSBlurEffectStyle blurEffect;
60
62
 
61
- + (void)willShowViewController:(UIViewController *)vc
63
+ NS_ASSUME_NONNULL_END
64
+
65
+ + (void)willShowViewController:(nonnull UIViewController *)vc
62
66
  animated:(BOOL)animated
63
- withConfig:(RNSScreenStackHeaderConfig *)config;
67
+ withConfig:(nonnull RNSScreenStackHeaderConfig *)config;
64
68
 
65
69
  /**
66
70
  * Allows to send information with insets to the corresponding node in shadow tree.
@@ -132,8 +136,7 @@
132
136
 
133
137
  @interface RCTConvert (RNSScreenStackHeader)
134
138
 
135
- + (UIBlurEffectStyle)UIBlurEffectStyle:(id)json;
136
- + (UISemanticContentAttribute)UISemanticContentAttribute:(id)json;
137
- + (UINavigationItemBackButtonDisplayMode)UINavigationItemBackButtonDisplayMode:(id)json;
139
+ + (UISemanticContentAttribute)UISemanticContentAttribute:(nonnull id)json;
140
+ + (UINavigationItemBackButtonDisplayMode)UINavigationItemBackButtonDisplayMode:(nonnull id)json;
138
141
 
139
142
  @end
@@ -10,6 +10,9 @@
10
10
  #import <react/renderer/components/rnscreens/RCTComponentViewHelpers.h>
11
11
  #import <rnscreens/RNSScreenStackHeaderConfigComponentDescriptor.h>
12
12
  #import "RCTImageComponentView+RNSScreenStackHeaderConfig.h"
13
+ #ifndef NDEBUG
14
+ #import <react/utils/ManagedObjectWrapper.h>
15
+ #endif // !NDEBUG
13
16
  #else
14
17
  #import <React/RCTImageView.h>
15
18
  #import <React/RCTShadowView.h>
@@ -21,6 +24,7 @@
21
24
  #import <React/RCTImageLoader.h>
22
25
  #import <React/RCTImageSource.h>
23
26
  #import "RNSConvert.h"
27
+ #import "RNSDefines.h"
24
28
  #import "RNSScreen.h"
25
29
  #import "RNSScreenStackHeaderConfig.h"
26
30
  #import "RNSSearchBar.h"
@@ -60,6 +64,9 @@ namespace react = facebook::react;
60
64
  #ifdef RCT_NEW_ARCH_ENABLED
61
65
  BOOL _initialPropsSet;
62
66
  react::RNSScreenStackHeaderConfigShadowNode::ConcreteState::Shared _state;
67
+ #ifndef NDEBUG
68
+ RCTImageLoader *imageLoader;
69
+ #endif // !NDEBUG
63
70
  #else
64
71
  __weak RCTBridge *_bridge;
65
72
  #endif
@@ -113,6 +120,7 @@ namespace react = facebook::react;
113
120
  _blurEffect = RNSBlurEffectStyleNone;
114
121
  }
115
122
 
123
+ RNS_IGNORE_SUPER_CALL_BEGIN
116
124
  - (UIView *)reactSuperview
117
125
  {
118
126
  return _screenView;
@@ -122,6 +130,7 @@ namespace react = facebook::react;
122
130
  {
123
131
  return _reactSubviews;
124
132
  }
133
+ RNS_IGNORE_SUPER_CALL_END
125
134
 
126
135
  - (void)removeFromSuperview
127
136
  {
@@ -335,10 +344,10 @@ namespace react = facebook::react;
335
344
  [button setTitleTextAttributes:attrs forState:UIControlStateFocused];
336
345
  }
337
346
 
338
- + (UIImage *)loadBackButtonImageInViewController:(UIViewController *)vc withConfig:(RNSScreenStackHeaderConfig *)config
347
+ - (UIImage *)loadBackButtonImageInViewController:(UIViewController *)vc
339
348
  {
340
349
  BOOL hasBackButtonImage = NO;
341
- for (RNSScreenStackHeaderSubview *subview in config.reactSubviews) {
350
+ for (RNSScreenStackHeaderSubview *subview in self.reactSubviews) {
342
351
  if (subview.type == RNSScreenStackHeaderSubviewTypeBackButton && subview.subviews.count > 0) {
343
352
  hasBackButtonImage = YES;
344
353
  #ifdef RCT_NEW_ARCH_ENABLED
@@ -364,6 +373,7 @@ namespace react = facebook::react;
364
373
 
365
374
  UIImage *image = imageView.image;
366
375
 
376
+ #ifndef NDEBUG
367
377
  // IMPORTANT!!!
368
378
  // image can be nil in DEV MODE ONLY
369
379
  //
@@ -378,8 +388,9 @@ namespace react = facebook::react;
378
388
  // in DEV MODE we try to load from cache (we use private API for that as it is not exposed
379
389
  // publically in headers).
380
390
  RCTImageSource *imageSource = [RNSScreenStackHeaderConfig imageSourceFromImageView:imageView];
381
- RCTImageLoader *imageLoader = [subview.bridge moduleForClass:[RCTImageLoader class]];
382
-
391
+ #ifndef RCT_NEW_ARCH_ENABLED
392
+ RCTImageLoader *imageLoader = [_bridge moduleForClass:[RCTImageLoader class]];
393
+ #endif // !RCT_NEW_ARCH_ENABLED
383
394
  image = [imageLoader.imageCache
384
395
  imageForUrl:imageSource.request.URL.absoluteString
385
396
  size:imageSource.size
@@ -391,6 +402,7 @@ namespace react = facebook::react;
391
402
  resizeMode:imageView.resizeMode];
392
403
  #endif // RCT_NEW_ARCH_ENABLED
393
404
  }
405
+ #endif // !NDEBUG
394
406
  if (image == nil) {
395
407
  // This will be triggered if the image is not in the cache yet. What we do is we wait until
396
408
  // the end of transition and run header config updates again. We could potentially wait for
@@ -407,7 +419,7 @@ namespace react = facebook::react;
407
419
  #if !TARGET_OS_TV
408
420
  vc.navigationItem.hidesBackButton = YES;
409
421
  #endif
410
- [config updateViewControllerIfNeeded];
422
+ [self updateViewControllerIfNeeded];
411
423
  }];
412
424
  }
413
425
  return [UIImage new];
@@ -439,8 +451,16 @@ namespace react = facebook::react;
439
451
  UINavigationBarAppearance *appearance = [UINavigationBarAppearance new];
440
452
 
441
453
  if (config.backgroundColor && CGColorGetAlpha(config.backgroundColor.CGColor) == 0.) {
454
+ // Preserve the shadow properties in case the user wants to show the shadow on scroll.
455
+ UIColor *shadowColor = appearance.shadowColor;
456
+ UIImage *shadowImage = appearance.shadowImage;
442
457
  // transparent background color
443
458
  [appearance configureWithTransparentBackground];
459
+
460
+ if (!config.hideShadow) {
461
+ appearance.shadowColor = shadowColor;
462
+ appearance.shadowImage = shadowImage;
463
+ }
444
464
  } else {
445
465
  [appearance configureWithOpaqueBackground];
446
466
  }
@@ -517,7 +537,7 @@ namespace react = facebook::react;
517
537
  appearance.largeTitleTextAttributes = largeAttrs;
518
538
  }
519
539
 
520
- UIImage *backButtonImage = [self loadBackButtonImageInViewController:vc withConfig:config];
540
+ UIImage *backButtonImage = [config loadBackButtonImageInViewController:vc];
521
541
  if (backButtonImage) {
522
542
  [appearance setBackIndicatorImage:backButtonImage transitionMaskImage:backButtonImage];
523
543
  } else if (appearance.backIndicatorImage) {
@@ -668,7 +688,15 @@ namespace react = facebook::react;
668
688
  UINavigationBarAppearance *scrollEdgeAppearance =
669
689
  [[UINavigationBarAppearance alloc] initWithBarAppearance:appearance];
670
690
  if (config.largeTitleBackgroundColor != nil) {
671
- scrollEdgeAppearance.backgroundColor = config.largeTitleBackgroundColor;
691
+ // Add support for using a fully transparent bar when the backgroundColor is set to transparent.
692
+ if (CGColorGetAlpha(config.largeTitleBackgroundColor.CGColor) == 0.) {
693
+ // This will also remove the background blur effect in the large title which is otherwise inherited from the standard appearance.
694
+ [scrollEdgeAppearance configureWithTransparentBackground];
695
+ // This must be set to nil otherwise a default view will be added to the navigation bar background with an opaque background.
696
+ scrollEdgeAppearance.backgroundColor = nil;
697
+ } else {
698
+ scrollEdgeAppearance.backgroundColor = config.largeTitleBackgroundColor;
699
+ }
672
700
  }
673
701
  if (config.largeTitleHideShadow) {
674
702
  scrollEdgeAppearance.shadowColor = nil;
@@ -680,7 +708,7 @@ namespace react = facebook::react;
680
708
  #if !TARGET_OS_TV
681
709
  // updating backIndicatotImage does not work when called during transition. On iOS pre 13 we need
682
710
  // to update it before the navigation starts.
683
- UIImage *backButtonImage = [self loadBackButtonImageInViewController:vc withConfig:config];
711
+ UIImage *backButtonImage = [config loadBackButtonImageInViewController:vc];
684
712
  if (backButtonImage) {
685
713
  navctr.navigationBar.backIndicatorImage = backButtonImage;
686
714
  navctr.navigationBar.backIndicatorTransitionMaskImage = backButtonImage;
@@ -785,6 +813,7 @@ namespace react = facebook::react;
785
813
  }
786
814
  }
787
815
 
816
+ RNS_IGNORE_SUPER_CALL_BEGIN
788
817
  - (void)insertReactSubview:(RNSScreenStackHeaderSubview *)subview atIndex:(NSInteger)atIndex
789
818
  {
790
819
  [_reactSubviews insertObject:subview atIndex:atIndex];
@@ -795,6 +824,7 @@ namespace react = facebook::react;
795
824
  {
796
825
  [_reactSubviews removeObject:subview];
797
826
  }
827
+ RNS_IGNORE_SUPER_CALL_BEGIN
798
828
 
799
829
  - (void)didUpdateReactSubviews
800
830
  {
@@ -842,27 +872,29 @@ namespace react = facebook::react;
842
872
 
843
873
  - (void)replaceNavigationBarViewsWithSnapshotOfSubview:(RNSScreenStackHeaderSubview *)childComponentView
844
874
  {
845
- UINavigationItem *navitem = _screenView.controller.navigationItem;
846
- UIView *snapshot = [childComponentView snapshotViewAfterScreenUpdates:NO];
847
-
848
- // This code should be kept in sync with analogous switch statement in
849
- // `+ [RNSScreenStackHeaderConfig updateViewController: withConfig: animated:]` method.
850
- switch (childComponentView.type) {
851
- case RNSScreenStackHeaderSubviewTypeLeft:
852
- navitem.leftBarButtonItem.customView = snapshot;
853
- break;
854
- case RNSScreenStackHeaderSubviewTypeCenter:
855
- case RNSScreenStackHeaderSubviewTypeTitle:
856
- navitem.titleView = snapshot;
857
- break;
858
- case RNSScreenStackHeaderSubviewTypeRight:
859
- navitem.rightBarButtonItem.customView = snapshot;
860
- break;
861
- case RNSScreenStackHeaderSubviewTypeSearchBar:
862
- case RNSScreenStackHeaderSubviewTypeBackButton:
863
- break;
864
- default:
865
- RCTLogError(@"[RNScreens] Unhandled subview type: %ld", childComponentView.type);
875
+ if (childComponentView.window != nil) {
876
+ UINavigationItem *navitem = _screenView.controller.navigationItem;
877
+ UIView *snapshot = [childComponentView snapshotViewAfterScreenUpdates:NO];
878
+
879
+ // This code should be kept in sync with analogous switch statement in
880
+ // `+ [RNSScreenStackHeaderConfig updateViewController: withConfig: animated:]` method.
881
+ switch (childComponentView.type) {
882
+ case RNSScreenStackHeaderSubviewTypeLeft:
883
+ navitem.leftBarButtonItem.customView = snapshot;
884
+ break;
885
+ case RNSScreenStackHeaderSubviewTypeCenter:
886
+ case RNSScreenStackHeaderSubviewTypeTitle:
887
+ navitem.titleView = snapshot;
888
+ break;
889
+ case RNSScreenStackHeaderSubviewTypeRight:
890
+ navitem.rightBarButtonItem.customView = snapshot;
891
+ break;
892
+ case RNSScreenStackHeaderSubviewTypeSearchBar:
893
+ case RNSScreenStackHeaderSubviewTypeBackButton:
894
+ break;
895
+ default:
896
+ RCTLogError(@"[RNScreens] Unhandled subview type: %ld", childComponentView.type);
897
+ }
866
898
  }
867
899
  }
868
900
 
@@ -879,6 +911,9 @@ static RCTResizeMode resizeModeFromCppEquiv(react::ImageResizeMode resizeMode)
879
911
  return RCTResizeModeCenter;
880
912
  case react::ImageResizeMode::Repeat:
881
913
  return RCTResizeModeRepeat;
914
+ default:
915
+ // Both RCTConvert and ImageProps use this as a default as of RN 0.76
916
+ return RCTResizeModeStretch;
882
917
  }
883
918
  }
884
919
 
@@ -956,6 +991,7 @@ static RCTResizeMode resizeModeFromCppEquiv(react::ImageResizeMode resizeMode)
956
991
  _largeTitleFontWeight = RCTNSStringFromStringNilIfEmpty(newScreenProps.largeTitleFontWeight);
957
992
  _largeTitleFontSize = [self getFontSizePropValue:newScreenProps.largeTitleFontSize];
958
993
  _largeTitleHideShadow = newScreenProps.largeTitleHideShadow;
994
+ _largeTitleBackgroundColor = RCTUIColorFromSharedColor(newScreenProps.largeTitleBackgroundColor);
959
995
 
960
996
  _backTitle = RCTNSStringFromStringNilIfEmpty(newScreenProps.backTitle);
961
997
  if (newScreenProps.backTitleFontFamily != oldScreenProps.backTitleFontFamily) {
@@ -1000,6 +1036,11 @@ static RCTResizeMode resizeModeFromCppEquiv(react::ImageResizeMode resizeMode)
1000
1036
  oldState:(const facebook::react::State::Shared &)oldState
1001
1037
  {
1002
1038
  _state = std::static_pointer_cast<const react::RNSScreenStackHeaderConfigShadowNode::ConcreteState>(state);
1039
+ #ifndef NDEBUG
1040
+ if (auto imgLoaderPtr = _state.get()->getData().getImageLoader().lock()) {
1041
+ imageLoader = react::unwrapManagedObject(imgLoaderPtr);
1042
+ }
1043
+ #endif // !NDEBUG
1003
1044
  }
1004
1045
 
1005
1046
  #else
@@ -20,13 +20,6 @@ NS_ASSUME_NONNULL_BEGIN
20
20
 
21
21
  @property (nonatomic, weak) UIView *reactSuperview;
22
22
 
23
- @property (nonatomic, weak) RCTBridge *bridge;
24
-
25
- #ifdef RCT_NEW_ARCH_ENABLED
26
- #else
27
- - (instancetype)initWithBridge:(RCTBridge *)bridge;
28
- #endif // RCT_NEW_ARCH_ENABLED
29
-
30
23
  @end
31
24
 
32
25
  @interface RNSScreenStackHeaderSubviewManager : RCTViewManager
@@ -1,5 +1,6 @@
1
1
  #import "RNSScreenStackHeaderSubview.h"
2
2
  #import "RNSConvert.h"
3
+ #import "RNSDefines.h"
3
4
  #import "RNSScreenStackHeaderConfig.h"
4
5
 
5
6
  #ifdef RCT_NEW_ARCH_ENABLED
@@ -17,10 +18,6 @@
17
18
  namespace react = facebook::react;
18
19
  #endif // RCT_NEW_ARCH_ENABLED
19
20
 
20
- @interface RCTBridge (Private)
21
- + (RCTBridge *)currentBridge;
22
- @end
23
-
24
21
  @implementation RNSScreenStackHeaderSubview
25
22
 
26
23
  #pragma mark - Common
@@ -86,6 +83,8 @@ namespace react = facebook::react;
86
83
  return react::concreteComponentDescriptorProvider<react::RNSScreenStackHeaderSubviewComponentDescriptor>();
87
84
  }
88
85
 
86
+ RNS_IGNORE_SUPER_CALL_BEGIN
87
+ // System layouts the subviews.
89
88
  - (void)updateLayoutMetrics:(const react::LayoutMetrics &)layoutMetrics
90
89
  oldLayoutMetrics:(const react::LayoutMetrics &)oldLayoutMetrics
91
90
  {
@@ -105,23 +104,16 @@ namespace react = facebook::react;
105
104
  [self layoutNavigationBarIfNeeded];
106
105
  }
107
106
  }
107
+ RNS_IGNORE_SUPER_CALL_BEGIN
108
108
 
109
109
  + (BOOL)shouldBeRecycled
110
110
  {
111
111
  return NO;
112
112
  }
113
113
 
114
- #else
114
+ #else // RCT_NEW_ARCH_ENABLED
115
115
  #pragma mark - Paper specific
116
116
 
117
- - (instancetype)initWithBridge:(RCTBridge *)bridge
118
- {
119
- if (self = [super init]) {
120
- _bridge = bridge;
121
- }
122
- return self;
123
- }
124
-
125
117
  - (void)reactSetFrame:(CGRect)frame
126
118
  {
127
119
  // Block any attempt to set coordinates on RNSScreenStackHeaderSubview. This
@@ -129,18 +121,8 @@ namespace react = facebook::react;
129
121
  [super reactSetFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)];
130
122
  [self layoutNavigationBarIfNeeded];
131
123
  }
132
-
133
124
  #endif // RCT_NEW_ARCH_ENABLED
134
125
 
135
- - (RCTBridge *)bridge
136
- {
137
- #ifdef RCT_NEW_ARCH_ENABLED
138
- return [RCTBridge currentBridge];
139
- #else
140
- return _bridge;
141
- #endif // RCT_NEW_ARCH_ENABLED
142
- }
143
-
144
126
  @end
145
127
 
146
128
  @implementation RNSScreenStackHeaderSubviewManager
@@ -153,7 +135,7 @@ RCT_EXPORT_VIEW_PROPERTY(type, RNSScreenStackHeaderSubviewType)
153
135
  #else
154
136
  - (UIView *)view
155
137
  {
156
- return [[RNSScreenStackHeaderSubview alloc] initWithBridge:self.bridge];
138
+ return [RNSScreenStackHeaderSubview new];
157
139
  }
158
140
  #endif
159
141
 
@@ -1,4 +1,3 @@
1
- #import <React/RCTBridge+Private.h>
2
1
  #import <React/RCTEventDispatcherProtocol.h>
3
2
 
4
3
  @interface RNSHeaderHeightChangeEvent : NSObject <RCTEvent>
@@ -1,4 +1,3 @@
1
- #import <React/RCTBridge+Private.h>
2
1
  #import <React/RCTEventDispatcherProtocol.h>
3
2
 
4
3
  @interface RNSScreenViewEvent : NSObject <RCTEvent>
@@ -0,0 +1,7 @@
1
+ #pragma once
2
+
3
+ #define RNS_IGNORE_SUPER_CALL_BEGIN \
4
+ _Pragma("clang diagnostic push") \
5
+ _Pragma("clang diagnostic ignored \"-Wobjc-missing-super-calls\"")
6
+
7
+ #define RNS_IGNORE_SUPER_CALL_END _Pragma("clang diagnostic pop")
@@ -3,6 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ exports.FooterComponent = FooterComponent;
6
7
  exports.default = void 0;
7
8
  var _react = _interopRequireDefault(require("react"));
8
9
  var _ScreenFooterNativeComponent = _interopRequireDefault(require("../fabric/ScreenFooterNativeComponent"));
@@ -13,5 +14,13 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
13
14
  function ScreenFooter(props) {
14
15
  return /*#__PURE__*/_react.default.createElement(_ScreenFooterNativeComponent.default, props);
15
16
  }
17
+ function FooterComponent(_ref) {
18
+ let {
19
+ children
20
+ } = _ref;
21
+ return /*#__PURE__*/_react.default.createElement(ScreenFooter, {
22
+ collapsable: false
23
+ }, children);
24
+ }
16
25
  var _default = exports.default = ScreenFooter;
17
26
  //# sourceMappingURL=ScreenFooter.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["_react","_interopRequireDefault","require","_ScreenFooterNativeComponent","obj","__esModule","default","ScreenFooter","props","createElement","_default","exports"],"sourceRoot":"../../../src","sources":["components/ScreenFooter.tsx"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,sBAAA,CAAAC,OAAA;AAEA,IAAAC,4BAAA,GAAAF,sBAAA,CAAAC,OAAA;AAAgF,SAAAD,uBAAAG,GAAA,WAAAA,GAAA,IAAAA,GAAA,CAAAC,UAAA,GAAAD,GAAA,KAAAE,OAAA,EAAAF,GAAA;AAEhF;AACA;AACA;AACA,SAASG,YAAYA,CAACC,KAAgB,EAAE;EACtC,oBAAOR,MAAA,CAAAM,OAAA,CAAAG,aAAA,CAACN,4BAAA,CAAAG,OAA2B,EAAKE,KAAQ,CAAC;AACnD;AAAC,IAAAE,QAAA,GAAAC,OAAA,CAAAL,OAAA,GAEcC,YAAY"}
1
+ {"version":3,"names":["_react","_interopRequireDefault","require","_ScreenFooterNativeComponent","obj","__esModule","default","ScreenFooter","props","createElement","FooterComponent","_ref","children","collapsable","_default","exports"],"sourceRoot":"../../../src","sources":["components/ScreenFooter.tsx"],"mappings":";;;;;;;AAAA,IAAAA,MAAA,GAAAC,sBAAA,CAAAC,OAAA;AAEA,IAAAC,4BAAA,GAAAF,sBAAA,CAAAC,OAAA;AAAgF,SAAAD,uBAAAG,GAAA,WAAAA,GAAA,IAAAA,GAAA,CAAAC,UAAA,GAAAD,GAAA,KAAAE,OAAA,EAAAF,GAAA;AAEhF;AACA;AACA;AACA,SAASG,YAAYA,CAACC,KAAgB,EAAE;EACtC,oBAAOR,MAAA,CAAAM,OAAA,CAAAG,aAAA,CAACN,4BAAA,CAAAG,OAA2B,EAAKE,KAAQ,CAAC;AACnD;AAMO,SAASE,eAAeA,CAAAC,IAAA,EAA4B;EAAA,IAA3B;IAAEC;EAAsB,CAAC,GAAAD,IAAA;EACvD,oBAAOX,MAAA,CAAAM,OAAA,CAAAG,aAAA,CAACF,YAAY;IAACM,WAAW,EAAE;EAAM,GAAED,QAAuB,CAAC;AACpE;AAAC,IAAAE,QAAA,GAAAC,OAAA,CAAAT,OAAA,GAEcC,YAAY"}
@@ -12,6 +12,7 @@ var _ScreenStackHeaderConfig = require("./ScreenStackHeaderConfig");
12
12
  var _Screen = _interopRequireDefault(require("./Screen"));
13
13
  var _ScreenStack = _interopRequireDefault(require("./ScreenStack"));
14
14
  var _contexts = require("../contexts");
15
+ var _ScreenFooter = require("./ScreenFooter");
15
16
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
16
17
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
17
18
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
@@ -25,6 +26,8 @@ function ScreenStackItem(_ref, ref) {
25
26
  contentStyle,
26
27
  style,
27
28
  screenId,
29
+ // eslint-disable-next-line camelcase
30
+ unstable_sheetFooter,
28
31
  ...rest
29
32
  } = _ref;
30
33
  const currentScreenRef = React.useRef(null);
@@ -39,7 +42,7 @@ function ScreenStackItem(_ref, ref) {
39
42
  const content = /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_DebugContainer.default, {
40
43
  style: [stackPresentation === 'formSheet' ? _reactNative.Platform.OS === 'ios' ? styles.absolute : null : styles.container, contentStyle],
41
44
  stackPresentation: stackPresentation ?? 'push'
42
- }, children), /*#__PURE__*/React.createElement(_ScreenStackHeaderConfig.ScreenStackHeaderConfig, headerConfig));
45
+ }, children), /*#__PURE__*/React.createElement(_ScreenStackHeaderConfig.ScreenStackHeaderConfig, headerConfig), stackPresentation === 'formSheet' && unstable_sheetFooter && /*#__PURE__*/React.createElement(_ScreenFooter.FooterComponent, null, unstable_sheetFooter()));
43
46
 
44
47
  // We take backgroundColor from contentStyle and apply it on Screen.
45
48
  // This allows to workaround one issue with truncated