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.
Files changed (141) hide show
  1. package/README.md +2 -2
  2. package/RNScreens.podspec +5 -4
  3. package/android/build.gradle +18 -1
  4. package/android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt +8 -4
  5. package/android/src/main/java/com/swmansion/rnscreens/ScreenViewManager.kt +24 -6
  6. package/android/src/main/java/com/swmansion/rnscreens/ScreenWindowTraits.kt +18 -20
  7. package/android/src/main/jni/Android.mk +1 -2
  8. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenManagerDelegate.java +39 -14
  9. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenManagerInterface.java +15 -6
  10. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackHeaderConfigManagerDelegate.java +3 -3
  11. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackHeaderConfigManagerInterface.java +1 -1
  12. package/common/cpp/Android.mk +1 -2
  13. package/createNativeStackNavigator/README.md +4 -0
  14. package/ios/RNSConvert.h +30 -0
  15. package/ios/RNSConvert.mm +120 -0
  16. package/ios/RNSEnums.h +59 -0
  17. package/ios/RNSFullWindowOverlay.h +17 -2
  18. package/ios/RNSFullWindowOverlay.mm +199 -0
  19. package/ios/RNSScreen.h +70 -79
  20. package/ios/{RNSScreen.m → RNSScreen.mm} +679 -302
  21. package/ios/RNSScreenContainer.h +15 -1
  22. package/ios/{RNSScreenContainer.m → RNSScreenContainer.mm} +99 -8
  23. package/ios/{RNSScreenNavigationContainer.m → RNSScreenNavigationContainer.mm} +22 -0
  24. package/ios/RNSScreenStack.h +19 -3
  25. package/ios/{RNSScreenStack.m → RNSScreenStack.mm} +387 -124
  26. package/ios/{RNSScreenStackAnimator.m → RNSScreenStackAnimator.mm} +19 -14
  27. package/ios/RNSScreenStackHeaderConfig.h +20 -21
  28. package/ios/{RNSScreenStackHeaderConfig.m → RNSScreenStackHeaderConfig.mm} +232 -117
  29. package/ios/RNSScreenStackHeaderSubview.h +45 -0
  30. package/ios/RNSScreenStackHeaderSubview.mm +137 -0
  31. package/ios/RNSScreenViewEvent.h +12 -0
  32. package/ios/RNSScreenViewEvent.mm +59 -0
  33. package/ios/{RNSScreenWindowTraits.m → RNSScreenWindowTraits.mm} +3 -2
  34. package/ios/RNSSearchBar.h +14 -1
  35. package/ios/RNSSearchBar.mm +351 -0
  36. package/ios/{UIViewController+RNScreens.m → UIViewController+RNScreens.mm} +0 -0
  37. package/ios/{UIWindow+RNScreens.m → UIWindow+RNScreens.mm} +0 -0
  38. package/lib/commonjs/fabric/FullWindowOverlay.js +26 -0
  39. package/lib/commonjs/fabric/FullWindowOverlay.js.map +1 -0
  40. package/lib/commonjs/fabric/FullWindowOverlayNativeComponent.js +21 -0
  41. package/lib/commonjs/fabric/FullWindowOverlayNativeComponent.js.map +1 -0
  42. package/lib/commonjs/fabric/Screen.js +10 -8
  43. package/lib/commonjs/fabric/Screen.js.map +1 -1
  44. package/lib/commonjs/fabric/ScreenContainer.js +28 -0
  45. package/lib/commonjs/fabric/ScreenContainer.js.map +1 -0
  46. package/lib/commonjs/fabric/ScreenContainerNativeComponent.js +21 -0
  47. package/lib/commonjs/fabric/ScreenContainerNativeComponent.js.map +1 -0
  48. package/lib/commonjs/fabric/ScreenNativeComponent.js.map +1 -1
  49. package/lib/commonjs/fabric/ScreenNavigationContainer.js +28 -0
  50. package/lib/commonjs/fabric/ScreenNavigationContainer.js.map +1 -0
  51. package/lib/commonjs/fabric/ScreenNavigationContainerNativeComponent.js +21 -0
  52. package/lib/commonjs/fabric/ScreenNavigationContainerNativeComponent.js.map +1 -0
  53. package/lib/commonjs/fabric/ScreenStack.js +6 -7
  54. package/lib/commonjs/fabric/ScreenStack.js.map +1 -1
  55. package/lib/commonjs/fabric/ScreenStackHeaderConfigNativeComponent.js.map +1 -1
  56. package/lib/commonjs/fabric/ScreenStackHeaderSubview.js +4 -1
  57. package/lib/commonjs/fabric/ScreenStackHeaderSubview.js.map +1 -1
  58. package/lib/commonjs/fabric/ScreenStackNativeComponent.js.map +1 -1
  59. package/lib/commonjs/fabric/SearchBar.js +37 -0
  60. package/lib/commonjs/fabric/SearchBar.js.map +1 -0
  61. package/lib/commonjs/fabric/SearchBarNativeComponent.js +25 -0
  62. package/lib/commonjs/fabric/SearchBarNativeComponent.js.map +1 -0
  63. package/lib/commonjs/fabric/index.js +32 -0
  64. package/lib/commonjs/fabric/index.js.map +1 -1
  65. package/lib/commonjs/index.native.js +5 -18
  66. package/lib/commonjs/index.native.js.map +1 -1
  67. package/lib/commonjs/native-stack/views/NativeStackView.js +30 -0
  68. package/lib/commonjs/native-stack/views/NativeStackView.js.map +1 -1
  69. package/lib/commonjs/reanimated/ReanimatedNativeStackScreen.js +8 -2
  70. package/lib/commonjs/reanimated/ReanimatedNativeStackScreen.js.map +1 -1
  71. package/lib/module/fabric/FullWindowOverlay.js +15 -0
  72. package/lib/module/fabric/FullWindowOverlay.js.map +1 -0
  73. package/lib/module/fabric/FullWindowOverlayNativeComponent.js +9 -0
  74. package/lib/module/fabric/FullWindowOverlayNativeComponent.js.map +1 -0
  75. package/lib/module/fabric/Screen.js +8 -3
  76. package/lib/module/fabric/Screen.js.map +1 -1
  77. package/lib/module/fabric/ScreenContainer.js +17 -0
  78. package/lib/module/fabric/ScreenContainer.js.map +1 -0
  79. package/lib/module/fabric/ScreenContainerNativeComponent.js +9 -0
  80. package/lib/module/fabric/ScreenContainerNativeComponent.js.map +1 -0
  81. package/lib/module/fabric/ScreenNativeComponent.js.map +1 -1
  82. package/lib/module/fabric/ScreenNavigationContainer.js +17 -0
  83. package/lib/module/fabric/ScreenNavigationContainer.js.map +1 -0
  84. package/lib/module/fabric/ScreenNavigationContainerNativeComponent.js +9 -0
  85. package/lib/module/fabric/ScreenNavigationContainerNativeComponent.js.map +1 -0
  86. package/lib/module/fabric/ScreenStack.js +5 -2
  87. package/lib/module/fabric/ScreenStack.js.map +1 -1
  88. package/lib/module/fabric/ScreenStackHeaderConfigNativeComponent.js.map +1 -1
  89. package/lib/module/fabric/ScreenStackHeaderSubview.js +4 -1
  90. package/lib/module/fabric/ScreenStackHeaderSubview.js.map +1 -1
  91. package/lib/module/fabric/ScreenStackNativeComponent.js.map +1 -1
  92. package/lib/module/fabric/SearchBar.js +24 -0
  93. package/lib/module/fabric/SearchBar.js.map +1 -0
  94. package/lib/module/fabric/SearchBarNativeComponent.js +11 -0
  95. package/lib/module/fabric/SearchBarNativeComponent.js.map +1 -0
  96. package/lib/module/fabric/index.js +5 -1
  97. package/lib/module/fabric/index.js.map +1 -1
  98. package/lib/module/index.native.js +6 -20
  99. package/lib/module/index.native.js.map +1 -1
  100. package/lib/module/native-stack/views/NativeStackView.js +30 -0
  101. package/lib/module/native-stack/views/NativeStackView.js.map +1 -1
  102. package/lib/module/reanimated/ReanimatedNativeStackScreen.js +7 -2
  103. package/lib/module/reanimated/ReanimatedNativeStackScreen.js.map +1 -1
  104. package/lib/typescript/native-stack/types.d.ts +12 -0
  105. package/lib/typescript/reanimated/ReanimatedNativeStackScreen.d.ts +1 -1
  106. package/lib/typescript/reanimated/ReanimatedScreen.d.ts +1 -1
  107. package/lib/typescript/types.d.ts +24 -0
  108. package/native-stack/README.md +21 -0
  109. package/package.json +3 -4
  110. package/src/fabric/FullWindowOverlay.js +13 -0
  111. package/src/fabric/FullWindowOverlayNativeComponent.js +19 -0
  112. package/src/fabric/Screen.js +5 -2
  113. package/src/fabric/ScreenContainer.js +16 -0
  114. package/src/fabric/ScreenContainerNativeComponent.js +19 -0
  115. package/src/fabric/ScreenNativeComponent.js +41 -8
  116. package/src/fabric/ScreenNavigationContainer.js +16 -0
  117. package/src/fabric/ScreenNavigationContainerNativeComponent.js +19 -0
  118. package/src/fabric/ScreenStack.js +4 -2
  119. package/src/fabric/ScreenStackHeaderConfigNativeComponent.js +1 -1
  120. package/src/fabric/ScreenStackHeaderSubview.js +3 -1
  121. package/src/fabric/ScreenStackNativeComponent.js +4 -0
  122. package/src/fabric/SearchBar.js +20 -0
  123. package/src/fabric/SearchBarNativeComponent.js +62 -0
  124. package/src/fabric/index.js +8 -0
  125. package/src/index.native.tsx +13 -19
  126. package/src/native-stack/types.tsx +12 -0
  127. package/src/native-stack/views/NativeStackView.tsx +27 -0
  128. package/src/reanimated/ReanimatedNativeStackScreen.tsx +6 -0
  129. package/src/types.tsx +25 -0
  130. package/ios/RNSFullWindowOverlay.m +0 -105
  131. package/ios/RNSScreenComponentView.h +0 -23
  132. package/ios/RNSScreenComponentView.mm +0 -159
  133. package/ios/RNSScreenController.h +0 -10
  134. package/ios/RNSScreenController.mm +0 -79
  135. package/ios/RNSScreenStackComponentView.h +0 -15
  136. package/ios/RNSScreenStackComponentView.mm +0 -295
  137. package/ios/RNSScreenStackHeaderConfigComponentView.h +0 -42
  138. package/ios/RNSScreenStackHeaderConfigComponentView.mm +0 -662
  139. package/ios/RNSScreenStackHeaderSubviewComponentView.h +0 -14
  140. package/ios/RNSScreenStackHeaderSubviewComponentView.mm +0 -77
  141. package/ios/RNSSearchBar.m +0 -198
@@ -1,662 +0,0 @@
1
- #import "RNSScreenStackHeaderConfigComponentView.h"
2
- #import "RNSScreenStackHeaderSubviewComponentView.h"
3
-
4
- #import "./utils/RNSUIBarButtonItem.h"
5
-
6
- #import <React/RCTConversions.h>
7
- #import <React/RCTFont.h>
8
-
9
- #import <react/renderer/components/rnscreens/ComponentDescriptors.h>
10
- #import <react/renderer/components/rnscreens/EventEmitters.h>
11
- #import <react/renderer/components/rnscreens/Props.h>
12
- #import <react/renderer/components/rnscreens/RCTComponentViewHelpers.h>
13
-
14
- #import <React/UIView+React.h>
15
-
16
- #import "RCTFabricComponentsPlugins.h"
17
-
18
- using namespace facebook::react;
19
-
20
- @implementation RNSScreenStackHeaderConfigComponentView {
21
- BOOL _initialPropsSet;
22
- NSMutableArray<RNSScreenStackHeaderSubviewComponentView *> *_reactSubviews;
23
- SharedColor _backgroundSharedColor;
24
- }
25
-
26
- - (instancetype)initWithFrame:(CGRect)frame
27
- {
28
- if (self = [super initWithFrame:frame]) {
29
- static const auto defaultProps = std::make_shared<const RNSScreenStackHeaderConfigProps>();
30
- _props = defaultProps;
31
- self.hidden = YES;
32
- _show = YES;
33
- _translucent = NO;
34
- _reactSubviews = [NSMutableArray new];
35
- }
36
-
37
- return self;
38
- }
39
-
40
- - (UIView *)reactSuperview
41
- {
42
- return _screenView;
43
- }
44
-
45
- - (void)removeFromSuperview
46
- {
47
- [super removeFromSuperview];
48
- _screenView = nil;
49
- }
50
-
51
- // this method is never invoked by the system since this view
52
- // is not added to native view hierarchy so we can apply our logic
53
- - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
54
- {
55
- for (RNSScreenStackHeaderSubviewComponentView *subview in _reactSubviews) {
56
- if (subview.type == facebook::react::RNSScreenStackHeaderSubviewType::Left ||
57
- subview.type == facebook::react::RNSScreenStackHeaderSubviewType::Right) {
58
- // we wrap the headerLeft/Right component in a UIBarButtonItem
59
- // so we need to use the only subview of it to retrieve the correct view
60
- UIView *headerComponent = subview.subviews.firstObject;
61
- // we convert the point to RNSScreenStackView since it always contains the header inside it
62
- CGPoint convertedPoint = [_screenView.reactSuperview convertPoint:point toView:headerComponent];
63
-
64
- UIView *hitTestResult = [headerComponent hitTest:convertedPoint withEvent:event];
65
- if (hitTestResult != nil) {
66
- return hitTestResult;
67
- }
68
- }
69
- }
70
- return nil;
71
- }
72
-
73
- - (void)updateViewControllerIfNeeded
74
- {
75
- UIViewController *vc = _screenView.controller;
76
- UINavigationController *nav = (UINavigationController *)vc.parentViewController;
77
- UIViewController *nextVC = nav.visibleViewController;
78
- if (nav.transitionCoordinator != nil) {
79
- // if navigator is performing transition instead of allowing to update of `visibleConttroller`
80
- // we look at `topController`. This is because during transitiong the `visibleController` won't
81
- // point to the controller that is going to be revealed after transition. This check fixes the
82
- // problem when config gets updated while the transition is ongoing.
83
- nextVC = nav.topViewController;
84
- }
85
-
86
- if (vc != nil && (nextVC == vc)) {
87
- [RNSScreenStackHeaderConfigComponentView updateViewController:self.screenView.controller
88
- withConfig:self
89
- animated:YES];
90
- }
91
- }
92
-
93
- - (void)layoutNavigationControllerView
94
- {
95
- UIViewController *vc = _screenView.controller;
96
- UINavigationController *navctr = vc.navigationController;
97
- [navctr.view setNeedsLayout];
98
- }
99
-
100
- + (void)setAnimatedConfig:(UIViewController *)vc withConfig:(RNSScreenStackHeaderConfigComponentView *)config
101
- {
102
- UINavigationBar *navbar = ((UINavigationController *)vc.parentViewController).navigationBar;
103
- // It is workaround for loading custom back icon when transitioning from a screen without header to the screen which
104
- // has one. This action fails when navigating to the screen with header for the second time and loads default back
105
- // button. It looks like changing the tint color of navbar triggers an update of the items belonging to it and it
106
- // seems to load the custom back image so we change the tint color's alpha by a very small amount and then set it to
107
- // the one it should have.
108
- #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_14_0) && \
109
- __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_14_0
110
- // it brakes the behavior of `headerRight` in iOS 14, where the bug desribed above seems to be fixed, so we do nothing
111
- // in iOS 14
112
- if (@available(iOS 14.0, *)) {
113
- } else
114
- #endif
115
- {
116
- [navbar setTintColor:[config.color colorWithAlphaComponent:CGColorGetAlpha(config.color.CGColor) - 0.01]];
117
- }
118
- [navbar setTintColor:config.color];
119
-
120
- #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_13_0) && \
121
- __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_13_0
122
- if (@available(iOS 13.0, *)) {
123
- // font customized on the navigation item level, so nothing to do here
124
- } else
125
- #endif
126
- {
127
- BOOL hideShadow = config.hideShadow;
128
-
129
- if (config.backgroundColor && CGColorGetAlpha(config.backgroundColor.CGColor) == 0.) {
130
- [navbar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
131
- [navbar setBarTintColor:[UIColor clearColor]];
132
- hideShadow = YES;
133
- } else {
134
- [navbar setBackgroundImage:nil forBarMetrics:UIBarMetricsDefault];
135
- [navbar setBarTintColor:config.backgroundColor];
136
- }
137
- [navbar setTranslucent:config.translucent];
138
- [navbar setValue:@(hideShadow ? YES : NO) forKey:@"hidesShadow"];
139
-
140
- if (config.titleFontFamily || config.titleFontSize || config.titleFontWeight || config.titleColor) {
141
- NSMutableDictionary *attrs = [NSMutableDictionary new];
142
-
143
- if (config.titleColor) {
144
- attrs[NSForegroundColorAttributeName] = config.titleColor;
145
- }
146
-
147
- NSString *family = config.titleFontFamily ?: nil;
148
- NSNumber *size = config.titleFontSize ?: @17;
149
- NSString *weight = config.titleFontWeight ?: nil;
150
- if (family || weight) {
151
- attrs[NSFontAttributeName] = [RCTFont updateFont:nil
152
- withFamily:family
153
- size:size
154
- weight:weight
155
- style:nil
156
- variant:nil
157
- scaleMultiplier:1.0];
158
- } else {
159
- attrs[NSFontAttributeName] = [UIFont boldSystemFontOfSize:[size floatValue]];
160
- }
161
- [navbar setTitleTextAttributes:attrs];
162
- }
163
-
164
- #if !TARGET_OS_TV
165
- if (@available(iOS 11.0, *)) {
166
- if (config.largeTitle &&
167
- (config.largeTitleFontFamily || config.largeTitleFontSize || config.largeTitleFontWeight ||
168
- config.largeTitleColor || config.titleColor)) {
169
- NSMutableDictionary *largeAttrs = [NSMutableDictionary new];
170
- if (config.largeTitleColor || config.titleColor) {
171
- largeAttrs[NSForegroundColorAttributeName] =
172
- config.largeTitleColor ? config.largeTitleColor : config.titleColor;
173
- }
174
- NSString *largeFamily = config.largeTitleFontFamily ?: nil;
175
- NSNumber *largeSize = config.largeTitleFontSize ?: @34;
176
- NSString *largeWeight = config.largeTitleFontWeight ?: nil;
177
- if (largeFamily || largeWeight) {
178
- largeAttrs[NSFontAttributeName] = [RCTFont updateFont:nil
179
- withFamily:largeFamily
180
- size:largeSize
181
- weight:largeWeight
182
- style:nil
183
- variant:nil
184
- scaleMultiplier:1.0];
185
- } else {
186
- largeAttrs[NSFontAttributeName] = [UIFont systemFontOfSize:[largeSize floatValue] weight:UIFontWeightBold];
187
- }
188
- [navbar setLargeTitleTextAttributes:largeAttrs];
189
- }
190
- }
191
- #endif
192
- }
193
- }
194
-
195
- #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_13_0) && \
196
- __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_13_0
197
- + (UINavigationBarAppearance *)buildAppearance:(UIViewController *)vc
198
- withConfig:(RNSScreenStackHeaderConfigComponentView *)config
199
- API_AVAILABLE(ios(13.0))
200
- {
201
- UINavigationBarAppearance *appearance = [UINavigationBarAppearance new];
202
-
203
- if (config.backgroundColor && CGColorGetAlpha(config.backgroundColor.CGColor) == 0.) {
204
- // transparent background color
205
- [appearance configureWithTransparentBackground];
206
- } else {
207
- [appearance configureWithOpaqueBackground];
208
- }
209
-
210
- // set background color if specified
211
- if (config.backgroundColor) {
212
- appearance.backgroundColor = config.backgroundColor;
213
- }
214
-
215
- // if (config.blurEffect) {
216
- // appearance.backgroundEffect = [UIBlurEffect effectWithStyle:config.blurEffect];
217
- // }
218
-
219
- if (config.hideShadow) {
220
- appearance.shadowColor = nil;
221
- }
222
-
223
- if (config.titleFontFamily || config.titleFontSize || config.titleFontWeight || config.titleColor) {
224
- NSMutableDictionary *attrs = [NSMutableDictionary new];
225
-
226
- if (config.titleColor) {
227
- attrs[NSForegroundColorAttributeName] = config.titleColor;
228
- }
229
-
230
- NSString *family = config.titleFontFamily ?: nil;
231
- NSNumber *size = config.titleFontSize ?: @17;
232
- NSString *weight = config.titleFontWeight ?: nil;
233
- if (family || weight) {
234
- attrs[NSFontAttributeName] = [RCTFont updateFont:nil
235
- withFamily:config.titleFontFamily
236
- size:size
237
- weight:weight
238
- style:nil
239
- variant:nil
240
- scaleMultiplier:1.0];
241
- } else {
242
- attrs[NSFontAttributeName] = [UIFont boldSystemFontOfSize:[size floatValue]];
243
- }
244
- appearance.titleTextAttributes = attrs;
245
- }
246
-
247
- if (config.largeTitleFontFamily || config.largeTitleFontSize || config.largeTitleFontWeight ||
248
- config.largeTitleColor || config.titleColor) {
249
- NSMutableDictionary *largeAttrs = [NSMutableDictionary new];
250
-
251
- if (config.largeTitleColor || config.titleColor) {
252
- largeAttrs[NSForegroundColorAttributeName] = config.largeTitleColor ? config.largeTitleColor : config.titleColor;
253
- }
254
-
255
- NSString *largeFamily = config.largeTitleFontFamily ?: nil;
256
- NSNumber *largeSize = config.largeTitleFontSize ?: @34;
257
- NSString *largeWeight = config.largeTitleFontWeight ?: nil;
258
- if (largeFamily || largeWeight) {
259
- largeAttrs[NSFontAttributeName] = [RCTFont updateFont:nil
260
- withFamily:largeFamily
261
- size:largeSize
262
- weight:largeWeight
263
- style:nil
264
- variant:nil
265
- scaleMultiplier:1.0];
266
- } else {
267
- largeAttrs[NSFontAttributeName] = [UIFont systemFontOfSize:[largeSize floatValue] weight:UIFontWeightBold];
268
- }
269
-
270
- appearance.largeTitleTextAttributes = largeAttrs;
271
- }
272
-
273
- // UIImage *backButtonImage = [self loadBackButtonImageInViewController:vc withConfig:config];
274
- // if (backButtonImage) {
275
- // [appearance setBackIndicatorImage:backButtonImage transitionMaskImage:backButtonImage];
276
- // } else if (appearance.backIndicatorImage) {
277
- [appearance setBackIndicatorImage:nil transitionMaskImage:nil];
278
- // }
279
- return appearance;
280
- }
281
- #endif
282
-
283
- + (void)willShowViewController:(UIViewController *)vc
284
- animated:(BOOL)animated
285
- withConfig:(RNSScreenStackHeaderConfigComponentView *)config
286
- {
287
- [self updateViewController:vc withConfig:config animated:animated];
288
- }
289
-
290
- + (void)setTitleAttibutes:(NSDictionary *)attrs forButton:(UIBarButtonItem *)button
291
- {
292
- [button setTitleTextAttributes:attrs forState:UIControlStateNormal];
293
- [button setTitleTextAttributes:attrs forState:UIControlStateHighlighted];
294
- [button setTitleTextAttributes:attrs forState:UIControlStateDisabled];
295
- [button setTitleTextAttributes:attrs forState:UIControlStateSelected];
296
- [button setTitleTextAttributes:attrs forState:UIControlStateFocused];
297
- }
298
-
299
- + (UIImage *)loadBackButtonImageInViewController:(UIViewController *)vc
300
- withConfig:(RNSScreenStackHeaderConfigComponentView *)config
301
- {
302
- @throw([NSException exceptionWithName:@"UNIMPLEMENTED" reason:@"Implement" userInfo:nil]);
303
- return nil;
304
- }
305
-
306
- + (void)updateViewController:(UIViewController *)vc
307
- withConfig:(RNSScreenStackHeaderConfigComponentView *)config
308
- animated:(BOOL)animated
309
- {
310
- UINavigationItem *navitem = vc.navigationItem;
311
- UINavigationController *navctr = (UINavigationController *)vc.parentViewController;
312
-
313
- NSUInteger currentIndex = [navctr.viewControllers indexOfObject:vc];
314
- UINavigationItem *prevItem =
315
- currentIndex > 0 ? [navctr.viewControllers objectAtIndex:currentIndex - 1].navigationItem : nil;
316
-
317
- BOOL wasHidden = navctr.navigationBarHidden;
318
- BOOL shouldHide = config == nil || !config.show;
319
-
320
- if (!shouldHide && !config.translucent) {
321
- // when nav bar is not translucent we chage edgesForExtendedLayout to avoid system laying out
322
- // the screen underneath navigation controllers
323
- vc.edgesForExtendedLayout = UIRectEdgeNone;
324
- } else {
325
- // system default is UIRectEdgeAll
326
- vc.edgesForExtendedLayout = UIRectEdgeAll;
327
- }
328
-
329
- [navctr setNavigationBarHidden:shouldHide animated:animated];
330
-
331
- if ((config.direction == UISemanticContentAttributeForceLeftToRight ||
332
- config.direction == UISemanticContentAttributeForceRightToLeft) &&
333
- // iOS 12 cancels swipe gesture when direction is changed. See #1091
334
- navctr.view.semanticContentAttribute != config.direction) {
335
- navctr.view.semanticContentAttribute = config.direction;
336
- navctr.navigationBar.semanticContentAttribute = config.direction;
337
- }
338
-
339
- if (shouldHide) {
340
- return;
341
- }
342
-
343
- navitem.title = config.title;
344
- #if !TARGET_OS_TV
345
- if (config.backTitle != nil || config.backTitleFontFamily || config.backTitleFontSize ||
346
- config.disableBackButtonMenu) {
347
- RNSUIBarButtonItem *backBarButtonItem = [[RNSUIBarButtonItem alloc] initWithTitle:config.backTitle ?: prevItem.title
348
- style:UIBarButtonItemStylePlain
349
- target:nil
350
- action:nil];
351
-
352
- [backBarButtonItem setMenuHidden:config.disableBackButtonMenu];
353
-
354
- prevItem.backBarButtonItem = backBarButtonItem;
355
- if (config.backTitleFontFamily || config.backTitleFontSize) {
356
- NSMutableDictionary *attrs = [NSMutableDictionary new];
357
- NSNumber *size = config.backTitleFontSize ?: @17;
358
- if (config.backTitleFontFamily) {
359
- attrs[NSFontAttributeName] = [RCTFont updateFont:nil
360
- withFamily:config.backTitleFontFamily
361
- size:size
362
- weight:nil
363
- style:nil
364
- variant:nil
365
- scaleMultiplier:1.0];
366
- } else {
367
- attrs[NSFontAttributeName] = [UIFont boldSystemFontOfSize:[size floatValue]];
368
- }
369
- [self setTitleAttibutes:attrs forButton:prevItem.backBarButtonItem];
370
- }
371
- } else {
372
- prevItem.backBarButtonItem = nil;
373
- }
374
-
375
- if (@available(iOS 11.0, *)) {
376
- if (config.largeTitle) {
377
- navctr.navigationBar.prefersLargeTitles = YES;
378
- }
379
- navitem.largeTitleDisplayMode =
380
- config.largeTitle ? UINavigationItemLargeTitleDisplayModeAlways : UINavigationItemLargeTitleDisplayModeNever;
381
- }
382
- #endif
383
-
384
- #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_13_0) && \
385
- __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_13_0
386
- if (@available(iOS 13.0, tvOS 13.0, *)) {
387
- UINavigationBarAppearance *appearance = [self buildAppearance:vc withConfig:config];
388
- navitem.standardAppearance = appearance;
389
- navitem.compactAppearance = appearance;
390
-
391
- UINavigationBarAppearance *scrollEdgeAppearance =
392
- [[UINavigationBarAppearance alloc] initWithBarAppearance:appearance];
393
- if (config.largeTitleBackgroundColor != nil) {
394
- scrollEdgeAppearance.backgroundColor = config.largeTitleBackgroundColor;
395
- }
396
- if (config.largeTitleHideShadow) {
397
- scrollEdgeAppearance.shadowColor = nil;
398
- }
399
- navitem.scrollEdgeAppearance = scrollEdgeAppearance;
400
- } else
401
- #endif
402
- {
403
- #if !TARGET_OS_TV
404
- // updating backIndicatotImage does not work when called during transition. On iOS pre 13 we need
405
- // to update it before the navigation starts.
406
- UIImage *backButtonImage = [self loadBackButtonImageInViewController:vc withConfig:config];
407
- if (backButtonImage) {
408
- navctr.navigationBar.backIndicatorImage = backButtonImage;
409
- navctr.navigationBar.backIndicatorTransitionMaskImage = backButtonImage;
410
- } else if (navctr.navigationBar.backIndicatorImage) {
411
- navctr.navigationBar.backIndicatorImage = nil;
412
- navctr.navigationBar.backIndicatorTransitionMaskImage = nil;
413
- }
414
- #endif
415
- }
416
- #if !TARGET_OS_TV
417
- navitem.hidesBackButton = config.hideBackButton;
418
- #endif
419
- navitem.leftBarButtonItem = nil;
420
- navitem.rightBarButtonItem = nil;
421
- navitem.titleView = nil;
422
- for (RNSScreenStackHeaderSubviewComponentView *subview in config.reactSubviews) {
423
- switch (subview.type) {
424
- case RNSScreenStackHeaderSubviewType::Left: {
425
- //#if !TARGET_OS_TV
426
- // navitem.leftItemsSupplementBackButton = config.backButtonInCustomView;
427
- //#endif
428
- UIBarButtonItem *buttonItem = [[UIBarButtonItem alloc] initWithCustomView:subview];
429
- navitem.leftBarButtonItem = buttonItem;
430
- break;
431
- }
432
- case RNSScreenStackHeaderSubviewType::Right: {
433
- UIBarButtonItem *buttonItem = [[UIBarButtonItem alloc] initWithCustomView:subview];
434
- navitem.rightBarButtonItem = buttonItem;
435
- break;
436
- }
437
- case RNSScreenStackHeaderSubviewType::Center:
438
- case RNSScreenStackHeaderSubviewType::Title: {
439
- navitem.titleView = subview;
440
- break;
441
- }
442
- case RNSScreenStackHeaderSubviewType::SearchBar: {
443
- RCTLogWarn(@"SearchBar is not yet Fabric compatible in react-native-screens");
444
- break;
445
- }
446
- case RNSScreenStackHeaderSubviewType::Back: {
447
- RCTLogWarn(@"Back button subivew is not yet Fabric compatible in react-native-screens");
448
- break;
449
- ;
450
- }
451
- }
452
- }
453
-
454
- if (animated && vc.transitionCoordinator != nil &&
455
- vc.transitionCoordinator.presentationStyle == UIModalPresentationNone && !wasHidden) {
456
- // when there is an ongoing transition we may need to update navbar setting in animation block
457
- // using animateAlongsideTransition. However, we only do that given the transition is not a modal
458
- // transition (presentationStyle == UIModalPresentationNone) and that the bar was not previously
459
- // hidden. This is because both for modal transitions and transitions from screen with hidden bar
460
- // the transition animation block does not get triggered. This is ok, because with both of those
461
- // types of transitions there is no "shared" navigation bar that needs to be updated in an animated
462
- // way.
463
- [vc.transitionCoordinator
464
- animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
465
- [self setAnimatedConfig:vc withConfig:config];
466
- }
467
- completion:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
468
- if ([context isCancelled]) {
469
- UIViewController *fromVC = [context viewControllerForKey:UITransitionContextFromViewControllerKey];
470
- RNSScreenStackHeaderConfigComponentView *config = nil;
471
-
472
- // TODO: make sure this will exist in fabirc
473
- for (UIView *subview in fromVC.view.reactSubviews) {
474
- if ([subview isKindOfClass:[RNSScreenStackHeaderConfigComponentView class]]) {
475
- config = (RNSScreenStackHeaderConfigComponentView *)subview;
476
- break;
477
- }
478
- }
479
- [self setAnimatedConfig:fromVC withConfig:config];
480
- }
481
- }];
482
- } else {
483
- [self setAnimatedConfig:vc withConfig:config];
484
- }
485
- }
486
-
487
- + (void)addSubviewsToNavItem:(UINavigationItem *)navitem withConfig:(RNSScreenStackHeaderConfigComponentView *)config
488
- {
489
- for (RNSScreenStackHeaderSubviewComponentView *subview in config.reactSubviews) {
490
- switch (subview.type) {
491
- case facebook::react::RNSScreenStackHeaderSubviewType::Left: {
492
- UIBarButtonItem *buttonItem = [[UIBarButtonItem alloc] initWithCustomView:subview];
493
- navitem.leftBarButtonItem = buttonItem;
494
- break;
495
- }
496
- case facebook::react::RNSScreenStackHeaderSubviewType::Right: {
497
- UIBarButtonItem *buttonItem = [[UIBarButtonItem alloc] initWithCustomView:subview];
498
- navitem.rightBarButtonItem = buttonItem;
499
- break;
500
- }
501
- case facebook::react::RNSScreenStackHeaderSubviewType::Center:
502
- case facebook::react::RNSScreenStackHeaderSubviewType::Title: {
503
- navitem.titleView = subview;
504
- break;
505
- }
506
- case facebook::react::RNSScreenStackHeaderSubviewType::SearchBar: {
507
- RCTLogWarn(@"SearchBar is not yet supported in react-native-screens with Fabric enabled");
508
- break;
509
- }
510
- case facebook::react::RNSScreenStackHeaderSubviewType::Back: {
511
- break;
512
- }
513
- }
514
- }
515
- }
516
-
517
- - (void)mountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
518
- {
519
- if (![childComponentView isKindOfClass:[RNSScreenStackHeaderSubviewComponentView class]]) {
520
- RCTLogError(@"ScreenStackHeader only accepts children of type ScreenStackHeaderSubview");
521
- return;
522
- }
523
-
524
- RCTAssert(
525
- childComponentView.superview == nil,
526
- @"Attempt to mount already mounted component view. (parent: %@, child: %@, index: %@, existing parent: %@)",
527
- self,
528
- childComponentView,
529
- @(index),
530
- @([childComponentView.superview tag]));
531
-
532
- [_reactSubviews insertObject:(RNSScreenStackHeaderSubviewComponentView *)childComponentView atIndex:index];
533
- [self updateViewControllerIfNeeded];
534
- }
535
-
536
- - (void)unmountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
537
- {
538
- [_reactSubviews removeObject:(RNSScreenStackHeaderSubviewComponentView *)childComponentView];
539
- [childComponentView removeFromSuperview];
540
- }
541
-
542
- #pragma mark - RCTComponentViewProtocol
543
-
544
- - (void)prepareForRecycle
545
- {
546
- [super prepareForRecycle];
547
- _initialPropsSet = NO;
548
- }
549
-
550
- + (ComponentDescriptorProvider)componentDescriptorProvider
551
- {
552
- return concreteComponentDescriptorProvider<RNSScreenStackHeaderConfigComponentDescriptor>();
553
- }
554
-
555
- - (NSString *)getFontFamilyPropValue:(std::string)propValue
556
- {
557
- if (propValue.length() > 0) {
558
- return [[NSString alloc] initWithUTF8String:propValue.c_str()];
559
- } else {
560
- return nil;
561
- }
562
- }
563
-
564
- - (NSString *)stringToPropValue:(std::string)value
565
- {
566
- if (value.empty())
567
- return nil;
568
- return [[NSString alloc] initWithUTF8String:value.c_str()];
569
- }
570
-
571
- - (NSNumber *)getFontSizePropValue:(int)value
572
- {
573
- if (value > 0)
574
- return [NSNumber numberWithInt:value];
575
- return nil;
576
- }
577
-
578
- - (UISemanticContentAttribute)getDirectionPropValue:(RNSScreenStackHeaderConfigDirection)direction
579
- {
580
- switch (direction) {
581
- case RNSScreenStackHeaderConfigDirection::Rtl:
582
- return UISemanticContentAttributeForceRightToLeft;
583
- case RNSScreenStackHeaderConfigDirection::Ltr:
584
- return UISemanticContentAttributeForceLeftToRight;
585
- }
586
- }
587
-
588
- - (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps
589
- {
590
- [super updateProps:props oldProps:oldProps];
591
-
592
- const auto &oldScreenProps = *std::static_pointer_cast<const RNSScreenStackHeaderConfigProps>(_props);
593
- const auto &newScreenProps = *std::static_pointer_cast<const RNSScreenStackHeaderConfigProps>(props);
594
-
595
- BOOL needsNavigationControllerLayout = !_initialPropsSet;
596
-
597
- if (newScreenProps.hidden != !_show) {
598
- _show = !newScreenProps.hidden;
599
- needsNavigationControllerLayout = YES;
600
- }
601
-
602
- if (newScreenProps.translucent != _translucent) {
603
- _translucent = newScreenProps.translucent;
604
- needsNavigationControllerLayout = YES;
605
- }
606
-
607
- _title = [self stringToPropValue:newScreenProps.title];
608
- if (newScreenProps.titleFontFamily != oldScreenProps.titleFontFamily) {
609
- _titleFontFamily = [self getFontFamilyPropValue:newScreenProps.titleFontFamily];
610
- }
611
- _titleFontWeight = [self stringToPropValue:newScreenProps.titleFontWeight];
612
- _titleFontSize = [self getFontSizePropValue:newScreenProps.titleFontSize];
613
- _hideShadow = newScreenProps.hideShadow;
614
-
615
- _largeTitle = newScreenProps.largeTitle;
616
- if (newScreenProps.largeTitleFontFamily != oldScreenProps.largeTitleFontFamily) {
617
- _largeTitleFontFamily = [self getFontFamilyPropValue:newScreenProps.largeTitleFontFamily];
618
- }
619
- _largeTitleFontWeight = [self stringToPropValue:newScreenProps.largeTitleFontWeight];
620
- _largeTitleFontSize = [self getFontSizePropValue:newScreenProps.largeTitleFontSize];
621
- _largeTitleHideShadow = newScreenProps.largeTitleHideShadow;
622
-
623
- _backTitle = [self stringToPropValue:newScreenProps.backTitle];
624
- ;
625
- if (newScreenProps.backTitleFontFamily != oldScreenProps.backTitleFontFamily) {
626
- _backTitleFontFamily = [self getFontFamilyPropValue:newScreenProps.backTitleFontFamily];
627
- }
628
- _backTitleFontSize = [self getFontSizePropValue:newScreenProps.backTitleFontSize];
629
- _hideBackButton = newScreenProps.hideBackButton;
630
- _disableBackButtonMenu = newScreenProps.disableBackButtonMenu;
631
-
632
- if (newScreenProps.direction != oldScreenProps.direction) {
633
- _direction = [self getDirectionPropValue:newScreenProps.direction];
634
- }
635
-
636
- // We cannot compare SharedColor because it is shared value.
637
- // We could compare color value, but it is more performant to just assign new value
638
- _titleColor = RCTUIColorFromSharedColor(newScreenProps.titleColor);
639
- _largeTitleColor = RCTUIColorFromSharedColor(newScreenProps.largeTitleColor);
640
- _color = RCTUIColorFromSharedColor(newScreenProps.color);
641
-
642
- if (_backgroundSharedColor != newScreenProps.backgroundColor) {
643
- _backgroundSharedColor = newScreenProps.backgroundColor;
644
- _backgroundColor = RCTUIColorFromSharedColor(_backgroundSharedColor);
645
- }
646
-
647
- [self updateViewControllerIfNeeded];
648
-
649
- if (needsNavigationControllerLayout) {
650
- [self layoutNavigationControllerView];
651
- }
652
-
653
- _initialPropsSet = YES;
654
- _props = std::static_pointer_cast<RNSScreenStackHeaderConfigProps const>(props);
655
- }
656
-
657
- @end
658
-
659
- Class<RCTComponentViewProtocol> RNSScreenStackHeaderConfigCls(void)
660
- {
661
- return RNSScreenStackHeaderConfigComponentView.class;
662
- }
@@ -1,14 +0,0 @@
1
- #import <UIKit/UIKit.h>
2
-
3
- #import <React/RCTViewComponentView.h>
4
- #import <react/renderer/components/rnscreens/Props.h>
5
-
6
- NS_ASSUME_NONNULL_BEGIN
7
-
8
- @interface RNSScreenStackHeaderSubviewComponentView : RCTViewComponentView
9
-
10
- @property (nonatomic) facebook::react::RNSScreenStackHeaderSubviewType type;
11
-
12
- @end
13
-
14
- NS_ASSUME_NONNULL_END