react-native-screens 3.35.0-rc.0 → 4.0.0-beta.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/android/build.gradle +2 -2
- package/android/src/main/java/com/swmansion/rnscreens/InsetsObserverProxy.kt +67 -0
- package/android/src/main/java/com/swmansion/rnscreens/RNScreensPackage.kt +2 -0
- package/android/src/main/java/com/swmansion/rnscreens/Screen.kt +101 -4
- package/android/src/main/java/com/swmansion/rnscreens/ScreenContentWrapper.kt +38 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenContentWrapperManager.kt +25 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenFooter.kt +287 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenFooterManager.kt +25 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenFragment.kt +11 -19
- package/android/src/main/java/com/swmansion/rnscreens/ScreenFragmentWrapper.kt +4 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenModalFragment.kt +281 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt +62 -19
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragment.kt +403 -41
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragmentWrapper.kt +4 -1
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfig.kt +2 -2
- package/android/src/main/java/com/swmansion/rnscreens/ScreenViewManager.kt +95 -11
- package/android/src/main/java/com/swmansion/rnscreens/ScreenWindowTraits.kt +39 -28
- package/android/src/main/java/com/swmansion/rnscreens/bottomsheet/BottomSheetDialogRootView.kt +104 -0
- package/android/src/main/java/com/swmansion/rnscreens/bottomsheet/BottomSheetDialogScreen.kt +26 -0
- package/android/src/main/java/com/swmansion/rnscreens/bottomsheet/DimmingFragment.kt +488 -0
- package/android/src/main/java/com/swmansion/rnscreens/bottomsheet/DimmingView.kt +66 -0
- package/android/src/main/java/com/swmansion/rnscreens/bottomsheet/GestureTransparentViewGroup.kt +24 -0
- package/android/src/main/java/com/swmansion/rnscreens/bottomsheet/SheetUtils.kt +127 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/SheetDetentChangedEvent.kt +27 -0
- package/android/src/main/java/com/swmansion/rnscreens/ext/NumericExt.kt +12 -0
- package/android/src/main/java/com/swmansion/rnscreens/ext/ViewExt.kt +32 -0
- package/android/src/main/java/com/swmansion/rnscreens/utils/ScreenDummyLayoutHelper.kt +45 -8
- package/android/src/main/res/base/drawable/rns_rounder_top_corners_shape.xml +8 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenContentWrapperManagerDelegate.java +25 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenContentWrapperManagerInterface.java +16 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenFooterManagerDelegate.java +25 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenFooterManagerInterface.java +16 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenManagerDelegate.java +9 -2
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenManagerInterface.java +5 -2
- package/ios/RNSConvert.h +5 -3
- package/ios/RNSConvert.mm +14 -20
- package/ios/RNSScreen.h +3 -2
- package/ios/RNSScreen.mm +433 -49
- package/ios/RNSScreenContentWrapper.h +44 -0
- package/ios/RNSScreenContentWrapper.mm +61 -0
- package/ios/RNSScreenFooter.h +30 -0
- package/ios/RNSScreenFooter.mm +137 -0
- package/lib/commonjs/components/Screen.js +6 -2
- package/lib/commonjs/components/Screen.js.map +1 -1
- package/lib/commonjs/components/ScreenContentWrapper.js +19 -0
- package/lib/commonjs/components/ScreenContentWrapper.js.map +1 -0
- package/lib/commonjs/components/ScreenFooter.js +23 -0
- package/lib/commonjs/components/ScreenFooter.js.map +1 -0
- package/lib/commonjs/fabric/ModalScreenNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/ScreenContentWrapperNativeComponent.js +10 -0
- package/lib/commonjs/fabric/ScreenContentWrapperNativeComponent.js.map +1 -0
- package/lib/commonjs/fabric/ScreenFooterNativeComponent.js +10 -0
- package/lib/commonjs/fabric/ScreenFooterNativeComponent.js.map +1 -0
- package/lib/commonjs/fabric/ScreenNativeComponent.js.map +1 -1
- package/lib/commonjs/index.js +30 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/native-stack/views/FooterComponent.js +18 -0
- package/lib/commonjs/native-stack/views/FooterComponent.js.map +1 -0
- package/lib/commonjs/native-stack/views/NativeStackView.js +59 -14
- package/lib/commonjs/native-stack/views/NativeStackView.js.map +1 -1
- package/lib/module/components/Screen.js +6 -2
- package/lib/module/components/Screen.js.map +1 -1
- package/lib/module/components/ScreenContentWrapper.js +12 -0
- package/lib/module/components/ScreenContentWrapper.js.map +1 -0
- package/lib/module/components/ScreenFooter.js +17 -0
- package/lib/module/components/ScreenFooter.js.map +1 -0
- package/lib/module/fabric/ModalScreenNativeComponent.js.map +1 -1
- package/lib/module/fabric/ScreenContentWrapperNativeComponent.js +3 -0
- package/lib/module/fabric/ScreenContentWrapperNativeComponent.js.map +1 -0
- package/lib/module/fabric/ScreenFooterNativeComponent.js +3 -0
- package/lib/module/fabric/ScreenFooterNativeComponent.js.map +1 -0
- package/lib/module/fabric/ScreenNativeComponent.js.map +1 -1
- package/lib/module/index.js +2 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/native-stack/views/FooterComponent.js +11 -0
- package/lib/module/native-stack/views/FooterComponent.js.map +1 -0
- package/lib/module/native-stack/views/NativeStackView.js +61 -15
- package/lib/module/native-stack/views/NativeStackView.js.map +1 -1
- package/lib/typescript/components/Screen.d.ts.map +1 -1
- package/lib/typescript/components/ScreenContentWrapper.d.ts +6 -0
- package/lib/typescript/components/ScreenContentWrapper.d.ts.map +1 -0
- package/lib/typescript/components/ScreenFooter.d.ts +12 -0
- package/lib/typescript/components/ScreenFooter.d.ts.map +1 -0
- package/lib/typescript/fabric/ModalScreenNativeComponent.d.ts +2 -3
- package/lib/typescript/fabric/ModalScreenNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/ScreenContentWrapperNativeComponent.d.ts +7 -0
- package/lib/typescript/fabric/ScreenContentWrapperNativeComponent.d.ts.map +1 -0
- package/lib/typescript/fabric/ScreenFooterNativeComponent.d.ts +7 -0
- package/lib/typescript/fabric/ScreenFooterNativeComponent.d.ts.map +1 -0
- package/lib/typescript/fabric/ScreenNativeComponent.d.ts +9 -3
- package/lib/typescript/fabric/ScreenNativeComponent.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +2 -0
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/native-stack/types.d.ts +63 -23
- package/lib/typescript/native-stack/types.d.ts.map +1 -1
- package/lib/typescript/native-stack/views/FooterComponent.d.ts +7 -0
- package/lib/typescript/native-stack/views/FooterComponent.d.ts.map +1 -0
- package/lib/typescript/native-stack/views/NativeStackView.d.ts.map +1 -1
- package/lib/typescript/types.d.ts +42 -17
- package/lib/typescript/types.d.ts.map +1 -1
- package/native-stack/README.md +16 -14
- package/package.json +1 -1
- package/react-native.config.js +18 -16
- package/src/components/Screen.tsx +6 -2
- package/src/components/ScreenContentWrapper.tsx +12 -0
- package/src/components/ScreenFooter.tsx +18 -0
- package/src/fabric/ModalScreenNativeComponent.ts +2 -4
- package/src/fabric/ScreenContentWrapperNativeComponent.ts +9 -0
- package/src/fabric/ScreenFooterNativeComponent.ts +6 -0
- package/src/fabric/ScreenNativeComponent.ts +10 -4
- package/src/index.tsx +10 -0
- package/src/native-stack/types.tsx +57 -23
- package/src/native-stack/views/FooterComponent.tsx +10 -0
- package/src/native-stack/views/NativeStackView.tsx +74 -11
- package/src/types.tsx +41 -16
package/ios/RNSScreen.mm
CHANGED
|
@@ -2,12 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
#import "RNSScreen.h"
|
|
4
4
|
#import "RNSScreenContainer.h"
|
|
5
|
+
#import "RNSScreenContentWrapper.h"
|
|
5
6
|
#import "RNSScreenWindowTraits.h"
|
|
6
7
|
|
|
7
8
|
#ifdef RCT_NEW_ARCH_ENABLED
|
|
8
9
|
#import <React/RCTConversions.h>
|
|
9
10
|
#import <React/RCTFabricComponentsPlugins.h>
|
|
10
11
|
#import <React/RCTRootComponentView.h>
|
|
12
|
+
#import <React/RCTScrollViewComponentView.h>
|
|
11
13
|
#import <React/RCTSurfaceTouchHandler.h>
|
|
12
14
|
#import <react/renderer/components/rnscreens/EventEmitters.h>
|
|
13
15
|
#import <react/renderer/components/rnscreens/Props.h>
|
|
@@ -17,11 +19,15 @@
|
|
|
17
19
|
#import "RNSHeaderHeightChangeEvent.h"
|
|
18
20
|
#import "RNSScreenViewEvent.h"
|
|
19
21
|
#else
|
|
22
|
+
#import <React/RCTScrollView.h>
|
|
20
23
|
#import <React/RCTTouchHandler.h>
|
|
21
|
-
#endif
|
|
24
|
+
#endif // RCT_NEW_ARCH_ENABLED
|
|
22
25
|
|
|
23
26
|
#import <React/RCTShadowView.h>
|
|
24
27
|
#import <React/RCTUIManager.h>
|
|
28
|
+
#import <React/RCTUIManagerUtils.h>
|
|
29
|
+
|
|
30
|
+
#import "RNSScreenFooter.h"
|
|
25
31
|
#import "RNSScreenStack.h"
|
|
26
32
|
#import "RNSScreenStackHeaderConfig.h"
|
|
27
33
|
|
|
@@ -29,22 +35,38 @@
|
|
|
29
35
|
|
|
30
36
|
#ifdef RCT_NEW_ARCH_ENABLED
|
|
31
37
|
namespace react = facebook::react;
|
|
38
|
+
#define ReactScrollViewBase RCTScrollViewComponentView
|
|
39
|
+
#else
|
|
40
|
+
#define ReactScrollViewBase RCTScrollView
|
|
32
41
|
#endif // RCT_NEW_ARCH_ENABLED
|
|
33
42
|
|
|
34
|
-
|
|
43
|
+
constexpr NSInteger SHEET_FIT_TO_CONTENTS = -1;
|
|
44
|
+
constexpr NSInteger SHEET_LARGEST_UNDIMMED_DETENT_NONE = -1;
|
|
45
|
+
|
|
46
|
+
@interface RNSScreenView () <
|
|
47
|
+
UIAdaptivePresentationControllerDelegate,
|
|
48
|
+
RNSScreenContentWrapperDelegate,
|
|
49
|
+
#if !TARGET_OS_TV
|
|
50
|
+
UISheetPresentationControllerDelegate,
|
|
51
|
+
#endif
|
|
35
52
|
#ifdef RCT_NEW_ARCH_ENABLED
|
|
36
|
-
|
|
53
|
+
RCTRNSScreenViewProtocol,
|
|
54
|
+
CAAnimationDelegate>
|
|
37
55
|
#else
|
|
38
|
-
|
|
56
|
+
RCTInvalidating>
|
|
39
57
|
#endif
|
|
58
|
+
|
|
40
59
|
@end
|
|
41
60
|
|
|
42
61
|
@implementation RNSScreenView {
|
|
62
|
+
__weak ReactScrollViewBase *_sheetsScrollView;
|
|
63
|
+
BOOL _didSetSheetAllowedDetentsOnController;
|
|
43
64
|
#ifdef RCT_NEW_ARCH_ENABLED
|
|
44
65
|
RCTSurfaceTouchHandler *_touchHandler;
|
|
45
66
|
react::RNSScreenShadowNode::ConcreteState::Shared _state;
|
|
46
67
|
// on fabric, they are not available by default so we need them exposed here too
|
|
47
68
|
NSMutableArray<UIView *> *_reactSubviews;
|
|
69
|
+
__weak RNSScreenContentWrapper *_contentWrapper;
|
|
48
70
|
#else
|
|
49
71
|
__weak RCTBridge *_bridge;
|
|
50
72
|
RCTTouchHandler *_touchHandler;
|
|
@@ -59,6 +81,7 @@ namespace react = facebook::react;
|
|
|
59
81
|
static const auto defaultProps = std::make_shared<const react::RNSScreenProps>();
|
|
60
82
|
_props = defaultProps;
|
|
61
83
|
_reactSubviews = [NSMutableArray new];
|
|
84
|
+
_contentWrapper = nil;
|
|
62
85
|
[self initCommonProps];
|
|
63
86
|
}
|
|
64
87
|
return self;
|
|
@@ -91,6 +114,8 @@ namespace react = facebook::react;
|
|
|
91
114
|
#if !TARGET_OS_TV
|
|
92
115
|
_sheetExpandsWhenScrolledToEdge = YES;
|
|
93
116
|
#endif // !TARGET_OS_TV
|
|
117
|
+
_sheetsScrollView = nil;
|
|
118
|
+
_didSetSheetAllowedDetentsOnController = NO;
|
|
94
119
|
}
|
|
95
120
|
|
|
96
121
|
- (UIViewController *)reactViewController
|
|
@@ -121,7 +146,49 @@ namespace react = facebook::react;
|
|
|
121
146
|
}
|
|
122
147
|
#else
|
|
123
148
|
[_bridge.uiManager setSize:self.bounds.size forView:self];
|
|
124
|
-
#endif
|
|
149
|
+
#endif // RCT_NEW_ARCH_ENABLED
|
|
150
|
+
|
|
151
|
+
if (_stackPresentation != RNSScreenStackPresentationFormSheet) {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// In case of formSheet stack presentation, to mitigate view flickering
|
|
156
|
+
// (see PR with description of this problem: https://github.com/software-mansion/react-native-screens/pull/1870)
|
|
157
|
+
// we do not set `bottom: 0` in JS for wrapper of the screen content, causing React to not set
|
|
158
|
+
// strict frame every time the sheet size is updated by the code above. This approach leads however to
|
|
159
|
+
// situation where (if present) scrollview does not know its view port size resulting in buggy behaviour.
|
|
160
|
+
// That's exactly the issue we are handling below. We look for a scroll view down the view hierarchy (only going
|
|
161
|
+
// through first subviews, as the OS does something similar e.g. when looking for scrollview for large header
|
|
162
|
+
// interaction) and we set its frame to the sheet size. **This is not perfect**, as the content might jump when items
|
|
163
|
+
// are added/removed to/from the scroll view, but it's the best we got rn. See
|
|
164
|
+
// https://github.com/software-mansion/react-native-screens/pull/1852
|
|
165
|
+
|
|
166
|
+
// TODO: Consider adding a prop to control whether we want to look for a scroll view here.
|
|
167
|
+
// It might be necessary in case someone doesn't want its scroll view to span over whole
|
|
168
|
+
// height of the sheet.
|
|
169
|
+
ReactScrollViewBase *scrollView = [self findDirectLineDescendantReactScrollView];
|
|
170
|
+
if (_sheetsScrollView != scrollView) {
|
|
171
|
+
[_sheetsScrollView removeObserver:self forKeyPath:@"bounds" context:nil];
|
|
172
|
+
_sheetsScrollView = scrollView;
|
|
173
|
+
|
|
174
|
+
// We pass 0 as options, as we are not interested in receiving updated bounds value,
|
|
175
|
+
// we are going to overwrite it anyway.
|
|
176
|
+
[scrollView addObserver:self forKeyPath:@"bounds" options:0 context:nil];
|
|
177
|
+
}
|
|
178
|
+
if (scrollView != nil) {
|
|
179
|
+
[scrollView setFrame:self.frame];
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
- (void)observeValueForKeyPath:(NSString *)keyPath
|
|
184
|
+
ofObject:(id)object
|
|
185
|
+
change:(NSDictionary<NSKeyValueChangeKey, id> *)change
|
|
186
|
+
context:(void *)context
|
|
187
|
+
{
|
|
188
|
+
UIView *scrollview = (UIView *)object;
|
|
189
|
+
if (!CGRectEqualToRect(scrollview.frame, self.frame)) {
|
|
190
|
+
[scrollview setFrame:self.frame];
|
|
191
|
+
}
|
|
125
192
|
}
|
|
126
193
|
|
|
127
194
|
- (void)setStackPresentation:(RNSScreenStackPresentation)stackPresentation
|
|
@@ -286,8 +353,41 @@ namespace react = facebook::react;
|
|
|
286
353
|
return _reactSuperview;
|
|
287
354
|
}
|
|
288
355
|
|
|
356
|
+
/// This is RNSScreenContentWrapperDelegate method, where we do get notified when React did update frame of our child.
|
|
357
|
+
- (void)reactDidSetFrame:(CGRect)reactFrame forContentWrapper:(RNSScreenContentWrapper *)contentWrapepr
|
|
358
|
+
{
|
|
359
|
+
if (self.stackPresentation != RNSScreenStackPresentationFormSheet || _didSetSheetAllowedDetentsOnController == YES) {
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
_didSetSheetAllowedDetentsOnController = YES;
|
|
364
|
+
|
|
365
|
+
#if !TARGET_OS_TV && !TARGET_OS_VISION && defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_16_0) && \
|
|
366
|
+
__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_16_0
|
|
367
|
+
if (@available(iOS 16.0, *)) {
|
|
368
|
+
UISheetPresentationController *sheetController = _controller.sheetPresentationController;
|
|
369
|
+
if (sheetController == nil) {
|
|
370
|
+
RCTLogError(@"[RNScreens] sheetPresentationController is null when attempting to set allowed detents");
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
if (_sheetAllowedDetents.count > 0 && _sheetAllowedDetents[0].intValue == SHEET_FIT_TO_CONTENTS) {
|
|
375
|
+
auto detents = [self detentsFromMaxHeights:@[ [NSNumber numberWithFloat:reactFrame.size.height] ]];
|
|
376
|
+
[self setAllowedDetentsForSheet:sheetController to:detents animate:YES];
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
#endif // Check for iOS >= 16 && !TARGET_OS_TV
|
|
380
|
+
}
|
|
381
|
+
|
|
289
382
|
- (void)addSubview:(UIView *)view
|
|
290
383
|
{
|
|
384
|
+
/// This system method is called on Paper only. Fabric uses `-[insertSubview:atIndex:]`.
|
|
385
|
+
if ([view isKindOfClass:RNSScreenContentWrapper.class] &&
|
|
386
|
+
self.stackPresentation == RNSScreenStackPresentationFormSheet) {
|
|
387
|
+
auto contentWrapper = (RNSScreenContentWrapper *)view;
|
|
388
|
+
contentWrapper.delegate = self;
|
|
389
|
+
}
|
|
390
|
+
|
|
291
391
|
if (![view isKindOfClass:[RNSScreenStackHeaderConfig class]]) {
|
|
292
392
|
[super addSubview:view];
|
|
293
393
|
} else {
|
|
@@ -403,13 +503,31 @@ namespace react = facebook::react;
|
|
|
403
503
|
#endif
|
|
404
504
|
}
|
|
405
505
|
|
|
506
|
+
- (void)notifySheetDetentChangeToIndex:(NSInteger)newDetentIndex isStable:(BOOL)isStable
|
|
507
|
+
{
|
|
508
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
509
|
+
if (_eventEmitter != nullptr) {
|
|
510
|
+
int index = newDetentIndex;
|
|
511
|
+
std::dynamic_pointer_cast<const react::RNSScreenEventEmitter>(_eventEmitter)
|
|
512
|
+
->onSheetDetentChanged(
|
|
513
|
+
react::RNSScreenEventEmitter::OnSheetDetentChanged{.index = index, .isStable = isStable});
|
|
514
|
+
}
|
|
515
|
+
#else
|
|
516
|
+
if (self.onSheetDetentChanged) {
|
|
517
|
+
self.onSheetDetentChanged(@{
|
|
518
|
+
@"index" : @(newDetentIndex),
|
|
519
|
+
@"isStable" : @(YES),
|
|
520
|
+
});
|
|
521
|
+
}
|
|
522
|
+
#endif
|
|
523
|
+
}
|
|
524
|
+
|
|
406
525
|
- (void)notifyHeaderHeightChange:(double)headerHeight
|
|
407
526
|
{
|
|
408
527
|
#ifdef RCT_NEW_ARCH_ENABLED
|
|
409
528
|
if (_eventEmitter != nullptr) {
|
|
410
|
-
std::dynamic_pointer_cast<const
|
|
411
|
-
->onHeaderHeightChange(
|
|
412
|
-
facebook::react::RNSScreenEventEmitter::OnHeaderHeightChange{.headerHeight = headerHeight});
|
|
529
|
+
std::dynamic_pointer_cast<const react::RNSScreenEventEmitter>(_eventEmitter)
|
|
530
|
+
->onHeaderHeightChange(react::RNSScreenEventEmitter::OnHeaderHeightChange{.headerHeight = headerHeight});
|
|
413
531
|
}
|
|
414
532
|
|
|
415
533
|
RNSHeaderHeightChangeEvent *event =
|
|
@@ -579,6 +697,19 @@ namespace react = facebook::react;
|
|
|
579
697
|
return nil;
|
|
580
698
|
}
|
|
581
699
|
|
|
700
|
+
/// Looks for RCTScrollView in direct line - goes through the subviews at index 0 down the view hierarchy.
|
|
701
|
+
- (nullable ReactScrollViewBase *)findDirectLineDescendantReactScrollView
|
|
702
|
+
{
|
|
703
|
+
UIView *firstSubview = self;
|
|
704
|
+
while (firstSubview.subviews.count > 0) {
|
|
705
|
+
firstSubview = firstSubview.subviews[0];
|
|
706
|
+
if ([firstSubview isKindOfClass:ReactScrollViewBase.class]) {
|
|
707
|
+
return (ReactScrollViewBase *)firstSubview;
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
return nil;
|
|
711
|
+
}
|
|
712
|
+
|
|
582
713
|
- (BOOL)isModal
|
|
583
714
|
{
|
|
584
715
|
return self.stackPresentation != RNSScreenStackPresentationPush;
|
|
@@ -608,58 +739,295 @@ namespace react = facebook::react;
|
|
|
608
739
|
}
|
|
609
740
|
|
|
610
741
|
#if !TARGET_OS_TV && !TARGET_OS_VISION
|
|
742
|
+
|
|
743
|
+
- (void)setPropertyForSheet:(UISheetPresentationController *)sheet
|
|
744
|
+
withBlock:(void (^)(void))block
|
|
745
|
+
animate:(BOOL)animate API_AVAILABLE(ios(15.0))
|
|
746
|
+
{
|
|
747
|
+
if (animate) {
|
|
748
|
+
[sheet animateChanges:block];
|
|
749
|
+
} else {
|
|
750
|
+
block();
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
- (void)setAllowedDetentsForSheet:(UISheetPresentationController *)sheet
|
|
755
|
+
to:(NSArray<UISheetPresentationControllerDetent *> *)detents
|
|
756
|
+
animate:(BOOL)animate API_AVAILABLE(ios(15.0))
|
|
757
|
+
{
|
|
758
|
+
[self setPropertyForSheet:sheet
|
|
759
|
+
withBlock:^{
|
|
760
|
+
sheet.detents = detents;
|
|
761
|
+
}
|
|
762
|
+
animate:animate];
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
- (void)setSelectedDetentForSheet:(UISheetPresentationController *)sheet
|
|
766
|
+
to:(UISheetPresentationControllerDetentIdentifier)detent
|
|
767
|
+
animate:(BOOL)animate API_AVAILABLE(ios(15.0))
|
|
768
|
+
{
|
|
769
|
+
if (sheet.selectedDetentIdentifier != detent) {
|
|
770
|
+
[self setPropertyForSheet:sheet
|
|
771
|
+
withBlock:^{
|
|
772
|
+
sheet.selectedDetentIdentifier = detent;
|
|
773
|
+
}
|
|
774
|
+
animate:animate];
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
- (void)setCornerRadiusForSheet:(UISheetPresentationController *)sheet
|
|
779
|
+
to:(CGFloat)radius
|
|
780
|
+
animate:(BOOL)animate API_AVAILABLE(ios(15.0))
|
|
781
|
+
{
|
|
782
|
+
if (sheet.preferredCornerRadius != radius) {
|
|
783
|
+
[self setPropertyForSheet:sheet
|
|
784
|
+
withBlock:^{
|
|
785
|
+
sheet.preferredCornerRadius =
|
|
786
|
+
radius < 0 ? UISheetPresentationControllerAutomaticDimension : radius;
|
|
787
|
+
}
|
|
788
|
+
animate:animate];
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
- (void)setGrabberVisibleForSheet:(UISheetPresentationController *)sheet
|
|
793
|
+
to:(BOOL)visible
|
|
794
|
+
animate:(BOOL)animate API_AVAILABLE(ios(15.0))
|
|
795
|
+
{
|
|
796
|
+
if (sheet.prefersGrabberVisible != visible) {
|
|
797
|
+
[self setPropertyForSheet:sheet
|
|
798
|
+
withBlock:^{
|
|
799
|
+
sheet.prefersGrabberVisible = visible;
|
|
800
|
+
}
|
|
801
|
+
animate:animate];
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
- (void)setLargestUndimmedDetentForSheet:(UISheetPresentationController *)sheet
|
|
806
|
+
to:(UISheetPresentationControllerDetentIdentifier)detent
|
|
807
|
+
animate:(BOOL)animate API_AVAILABLE(ios(15.0))
|
|
808
|
+
{
|
|
809
|
+
if (sheet.largestUndimmedDetentIdentifier != detent) {
|
|
810
|
+
[self setPropertyForSheet:sheet
|
|
811
|
+
withBlock:^{
|
|
812
|
+
sheet.largestUndimmedDetentIdentifier = detent;
|
|
813
|
+
}
|
|
814
|
+
animate:animate];
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_15_0) && \
|
|
819
|
+
__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_15_0
|
|
820
|
+
- (NSInteger)detentIndexFromDetentIdentifier:(UISheetPresentationControllerDetentIdentifier)identifier
|
|
821
|
+
API_AVAILABLE(ios(15.0))
|
|
822
|
+
{
|
|
823
|
+
// We first check if we are running on iOS 16+ as the API is different
|
|
824
|
+
#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_16_0) && \
|
|
825
|
+
__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_16_0
|
|
826
|
+
if (_sheetAllowedDetents.count > 0) {
|
|
827
|
+
// We should be running on custom detents in this case, thus identifier should be a stringified number.
|
|
828
|
+
return identifier.integerValue;
|
|
829
|
+
} else
|
|
830
|
+
#endif // iOS 16 check
|
|
831
|
+
{
|
|
832
|
+
// We're using system defined identifiers.
|
|
833
|
+
if (_sheetAllowedDetents.count >= 2 || _sheetAllowedDetents.count == 0) {
|
|
834
|
+
if (identifier == UISheetPresentationControllerDetentIdentifierMedium) {
|
|
835
|
+
return 0;
|
|
836
|
+
} else if (identifier == UISheetPresentationControllerDetentIdentifierLarge) {
|
|
837
|
+
return 1;
|
|
838
|
+
} else {
|
|
839
|
+
RCTLogError(@"[RNScreens] Unexpected detent identifier %@", identifier);
|
|
840
|
+
}
|
|
841
|
+
} else {
|
|
842
|
+
// There is only single option.
|
|
843
|
+
return 0;
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
return 0;
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
- (void)sheetPresentationControllerDidChangeSelectedDetentIdentifier:
|
|
850
|
+
(UISheetPresentationController *)sheetPresentationController API_AVAILABLE(ios(15.0))
|
|
851
|
+
{
|
|
852
|
+
UISheetPresentationControllerDetentIdentifier ident = sheetPresentationController.selectedDetentIdentifier;
|
|
853
|
+
[self notifySheetDetentChangeToIndex:[self detentIndexFromDetentIdentifier:ident] isStable:YES];
|
|
854
|
+
}
|
|
855
|
+
#endif // iOS 15 check
|
|
856
|
+
|
|
611
857
|
/**
|
|
612
858
|
* Updates settings for sheet presentation controller.
|
|
613
859
|
* Note that this method should not be called inside `stackPresentation` setter, because on Paper we don't have
|
|
614
|
-
* guarantee that values of all related props had been updated earlier.
|
|
860
|
+
* guarantee that values of all related props had been updated earlier. It should be invoked from `didSetProps`.
|
|
861
|
+
* On Fabric we have control over prop-setting process but it might be reasonable to run it from `finalizeUpdates`.
|
|
615
862
|
*/
|
|
616
|
-
- (void)
|
|
863
|
+
- (void)updateFormSheetPresentationStyle
|
|
617
864
|
{
|
|
865
|
+
if (_stackPresentation != RNSScreenStackPresentationFormSheet) {
|
|
866
|
+
return;
|
|
867
|
+
}
|
|
618
868
|
#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_15_0) && \
|
|
619
869
|
__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_15_0
|
|
870
|
+
int firstDimmedDetentIndex = _sheetAllowedDetents.count;
|
|
871
|
+
|
|
872
|
+
// Whether we use system (iOS 15) detents or custom (iOS 16+).
|
|
873
|
+
// Custom detents are in use if we are on iOS 16+ and we have at least single detent
|
|
874
|
+
// defined in the detents array. In any other case we do use system defined detents.
|
|
875
|
+
bool systemDetentsInUse = false;
|
|
876
|
+
|
|
620
877
|
if (@available(iOS 15.0, *)) {
|
|
621
878
|
UISheetPresentationController *sheet = _controller.sheetPresentationController;
|
|
622
|
-
if (
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
879
|
+
if (sheet == nil) {
|
|
880
|
+
return;
|
|
881
|
+
}
|
|
882
|
+
sheet.delegate = self;
|
|
883
|
+
#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_16_0) && \
|
|
884
|
+
__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_16_0
|
|
885
|
+
if (_sheetAllowedDetents.count > 0) {
|
|
886
|
+
if (@available(iOS 16.0, *)) {
|
|
887
|
+
if (_sheetAllowedDetents.count == 1 && [_sheetAllowedDetents[0] integerValue] == SHEET_FIT_TO_CONTENTS) {
|
|
888
|
+
// This is `fitToContents` case, where sheet should be just high to display its contents.
|
|
889
|
+
// Paper: we do not set anything here, we will set once React computed layout of our React's children, namely
|
|
890
|
+
// RNSScreenContentWrapper, which in case of formSheet presentation style does have exactly the same frame as
|
|
891
|
+
// actual content. The update will be triggered once our child is mounted and laid out by React.
|
|
892
|
+
// Fabric: in this very moment our children are already mounted & laid out. In the very end of this method,
|
|
893
|
+
// after all other configuration is applied we trigger content wrapper to send us update on its frame.
|
|
894
|
+
} else {
|
|
895
|
+
[self setAllowedDetentsForSheet:sheet
|
|
896
|
+
to:[self detentsFromMaxHeightFractions:_sheetAllowedDetents]
|
|
897
|
+
animate:NO];
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
} else
|
|
901
|
+
#endif // Check for iOS >= 16
|
|
902
|
+
{
|
|
903
|
+
systemDetentsInUse = true;
|
|
904
|
+
if (_sheetAllowedDetents.count == 0) {
|
|
905
|
+
[self setAllowedDetentsForSheet:sheet
|
|
906
|
+
to:@[
|
|
907
|
+
UISheetPresentationControllerDetent.mediumDetent,
|
|
908
|
+
UISheetPresentationControllerDetent.largeDetent
|
|
909
|
+
]
|
|
910
|
+
animate:YES];
|
|
911
|
+
} else if (_sheetAllowedDetents.count >= 2) {
|
|
912
|
+
float firstDetentFraction = _sheetAllowedDetents[0].floatValue;
|
|
913
|
+
float secondDetentFraction = _sheetAllowedDetents[1].floatValue;
|
|
914
|
+
firstDimmedDetentIndex = 2;
|
|
915
|
+
|
|
916
|
+
if (firstDetentFraction < secondDetentFraction) {
|
|
917
|
+
[self setAllowedDetentsForSheet:sheet
|
|
918
|
+
to:@[
|
|
919
|
+
UISheetPresentationControllerDetent.mediumDetent,
|
|
920
|
+
UISheetPresentationControllerDetent.largeDetent
|
|
921
|
+
]
|
|
922
|
+
animate:YES];
|
|
923
|
+
} else {
|
|
924
|
+
RCTLogError(@"[RNScreens] The values in sheetAllowedDetents array must be sorted");
|
|
925
|
+
}
|
|
634
926
|
} else {
|
|
635
|
-
|
|
927
|
+
float firstDetentFraction = _sheetAllowedDetents[0].floatValue;
|
|
928
|
+
if (firstDetentFraction == SHEET_FIT_TO_CONTENTS) {
|
|
929
|
+
RCTLogError(@"[RNScreens] Unsupported on iOS versions below 16");
|
|
930
|
+
} else if (firstDetentFraction < 1.0) {
|
|
931
|
+
[self setAllowedDetentsForSheet:sheet to:@[ UISheetPresentationControllerDetent.mediumDetent ] animate:YES];
|
|
932
|
+
[self setSelectedDetentForSheet:sheet to:UISheetPresentationControllerDetentIdentifierMedium animate:YES];
|
|
933
|
+
} else {
|
|
934
|
+
[self setAllowedDetentsForSheet:sheet to:@[ UISheetPresentationControllerDetent.largeDetent ] animate:YES];
|
|
935
|
+
[self setSelectedDetentForSheet:sheet to:UISheetPresentationControllerDetentIdentifierLarge animate:YES];
|
|
936
|
+
}
|
|
636
937
|
}
|
|
938
|
+
}
|
|
637
939
|
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
940
|
+
sheet.prefersScrollingExpandsWhenScrolledToEdge = _sheetExpandsWhenScrolledToEdge;
|
|
941
|
+
[self setGrabberVisibleForSheet:sheet to:_sheetGrabberVisible animate:YES];
|
|
942
|
+
[self setCornerRadiusForSheet:sheet to:_sheetCornerRadius animate:YES];
|
|
943
|
+
|
|
944
|
+
// lud - largest undimmed detent
|
|
945
|
+
// First we try to take value from the prop or default.
|
|
946
|
+
int ludIndex = _sheetLargestUndimmedDetent != nil ? _sheetLargestUndimmedDetent.intValue : -1;
|
|
947
|
+
// Rationalize the value in case the user set something that did not make sense.
|
|
948
|
+
ludIndex = ludIndex >= firstDimmedDetentIndex ? firstDimmedDetentIndex - 1 : ludIndex;
|
|
949
|
+
if (ludIndex == SHEET_LARGEST_UNDIMMED_DETENT_NONE) {
|
|
950
|
+
[self setLargestUndimmedDetentForSheet:sheet to:nil animate:YES];
|
|
951
|
+
} else if (ludIndex >= 0) {
|
|
952
|
+
if (systemDetentsInUse) {
|
|
953
|
+
// We're on iOS 15 or do not have custom detents specified by the user.
|
|
954
|
+
if (firstDimmedDetentIndex == 0 || (firstDimmedDetentIndex == 1 && _sheetAllowedDetents[0].floatValue < 1.0)) {
|
|
955
|
+
// There are no detents specified or there is exactly one & it is less than 1.0 we default to medium.
|
|
956
|
+
[self setLargestUndimmedDetentForSheet:sheet
|
|
957
|
+
to:UISheetPresentationControllerDetentIdentifierMedium
|
|
958
|
+
animate:YES];
|
|
959
|
+
} else {
|
|
960
|
+
[self setLargestUndimmedDetentForSheet:sheet
|
|
961
|
+
to:UISheetPresentationControllerDetentIdentifierLarge
|
|
962
|
+
animate:YES];
|
|
651
963
|
}
|
|
652
|
-
} else if (_sheetAllowedDetents == RNSScreenDetentTypeAll) {
|
|
653
|
-
sheet.detents =
|
|
654
|
-
@[ UISheetPresentationControllerDetent.mediumDetent, UISheetPresentationControllerDetent.largeDetent ];
|
|
655
964
|
} else {
|
|
656
|
-
|
|
965
|
+
// We're on iOS 16+ & have custom detents.
|
|
966
|
+
[self setLargestUndimmedDetentForSheet:sheet to:[NSNumber numberWithInt:ludIndex].stringValue animate:YES];
|
|
657
967
|
}
|
|
968
|
+
} else {
|
|
969
|
+
RCTLogError(@"[RNScreens] Value of sheetLargestUndimmedDetent prop must be >= -1");
|
|
658
970
|
}
|
|
659
971
|
}
|
|
660
|
-
|
|
972
|
+
|
|
973
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
974
|
+
// We trigger update from content wrapper, because on Fabric we update props after the children are mounted & laid
|
|
975
|
+
// out.
|
|
976
|
+
[self->_contentWrapper triggerDelegateUpdate];
|
|
977
|
+
#endif // RCT_NEW_ARCH_ENABLED
|
|
978
|
+
#endif // Check for iOS >= 15
|
|
661
979
|
}
|
|
662
|
-
|
|
980
|
+
|
|
981
|
+
#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_16_0) && \
|
|
982
|
+
__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_16_0
|
|
983
|
+
|
|
984
|
+
/**
|
|
985
|
+
* Creates array of detent objects based on provided `values` & `resolver`. Since we need to name the detents to be able
|
|
986
|
+
* to later refer to them, this method names the detents by stringifying their indices, e.g. detent on index 2 will be
|
|
987
|
+
* named "2".
|
|
988
|
+
*/
|
|
989
|
+
- (NSArray<UISheetPresentationControllerDetent *> *)
|
|
990
|
+
detentsFromValues:(NSArray<NSNumber *> *)values
|
|
991
|
+
withResolver:(CGFloat (^)(id<UISheetPresentationControllerDetentResolutionContext>, NSNumber *))resolver
|
|
992
|
+
API_AVAILABLE(ios(16.0))
|
|
993
|
+
{
|
|
994
|
+
NSMutableArray<UISheetPresentationControllerDetent *> *customDetents =
|
|
995
|
+
[NSMutableArray arrayWithCapacity:values.count];
|
|
996
|
+
[values enumerateObjectsUsingBlock:^(NSNumber *value, NSUInteger index, BOOL *stop) {
|
|
997
|
+
UISheetPresentationControllerDetentIdentifier ident = [[NSNumber numberWithInt:index] stringValue];
|
|
998
|
+
[customDetents addObject:[UISheetPresentationControllerDetent
|
|
999
|
+
customDetentWithIdentifier:ident
|
|
1000
|
+
resolver:^CGFloat(
|
|
1001
|
+
id<UISheetPresentationControllerDetentResolutionContext> ctx) {
|
|
1002
|
+
return resolver(ctx, value);
|
|
1003
|
+
}]];
|
|
1004
|
+
}];
|
|
1005
|
+
return customDetents;
|
|
1006
|
+
}
|
|
1007
|
+
|
|
1008
|
+
- (NSArray<UISheetPresentationControllerDetent *> *)detentsFromMaxHeightFractions:(NSArray<NSNumber *> *)fractions
|
|
1009
|
+
API_AVAILABLE(ios(16.0))
|
|
1010
|
+
{
|
|
1011
|
+
return [self
|
|
1012
|
+
detentsFromValues:fractions
|
|
1013
|
+
withResolver:^CGFloat(id<UISheetPresentationControllerDetentResolutionContext> ctx, NSNumber *fraction) {
|
|
1014
|
+
return MIN(ctx.maximumDetentValue, ctx.maximumDetentValue * fraction.floatValue);
|
|
1015
|
+
}];
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
- (NSArray<UISheetPresentationControllerDetent *> *)detentsFromMaxHeights:(NSArray<NSNumber *> *)maxHeights
|
|
1019
|
+
API_AVAILABLE(ios(16.0))
|
|
1020
|
+
{
|
|
1021
|
+
return
|
|
1022
|
+
[self detentsFromValues:maxHeights
|
|
1023
|
+
withResolver:^CGFloat(id<UISheetPresentationControllerDetentResolutionContext> ctx, NSNumber *height) {
|
|
1024
|
+
return MIN(ctx.maximumDetentValue, height.floatValue);
|
|
1025
|
+
}];
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
#endif // Check for iOS >= 16
|
|
1029
|
+
|
|
1030
|
+
#endif // !TARGET_OS_TV && !TARGET_OS_VISION
|
|
663
1031
|
|
|
664
1032
|
#pragma mark - Fabric specific
|
|
665
1033
|
#ifdef RCT_NEW_ARCH_ENABLED
|
|
@@ -689,6 +1057,11 @@ namespace react = facebook::react;
|
|
|
689
1057
|
|
|
690
1058
|
- (void)mountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
|
|
691
1059
|
{
|
|
1060
|
+
if ([childComponentView isKindOfClass:RNSScreenContentWrapper.class]) {
|
|
1061
|
+
auto contentWrapper = (RNSScreenContentWrapper *)childComponentView;
|
|
1062
|
+
contentWrapper.delegate = self;
|
|
1063
|
+
_contentWrapper = contentWrapper;
|
|
1064
|
+
}
|
|
692
1065
|
if ([childComponentView isKindOfClass:[RNSScreenStackHeaderConfig class]]) {
|
|
693
1066
|
_config = (RNSScreenStackHeaderConfig *)childComponentView;
|
|
694
1067
|
_config.screenView = self;
|
|
@@ -702,6 +1075,10 @@ namespace react = facebook::react;
|
|
|
702
1075
|
if ([childComponentView isKindOfClass:[RNSScreenStackHeaderConfig class]]) {
|
|
703
1076
|
_config = nil;
|
|
704
1077
|
}
|
|
1078
|
+
if ([childComponentView isKindOfClass:[RNSScreenContentWrapper class]]) {
|
|
1079
|
+
_contentWrapper.delegate = nil;
|
|
1080
|
+
_contentWrapper = nil;
|
|
1081
|
+
}
|
|
705
1082
|
[_reactSubviews removeObject:childComponentView];
|
|
706
1083
|
[super unmountChildComponentView:childComponentView index:index];
|
|
707
1084
|
}
|
|
@@ -764,12 +1141,11 @@ namespace react = facebook::react;
|
|
|
764
1141
|
[self setSheetExpandsWhenScrolledToEdge:newScreenProps.sheetExpandsWhenScrolledToEdge];
|
|
765
1142
|
|
|
766
1143
|
if (newScreenProps.sheetAllowedDetents != oldScreenProps.sheetAllowedDetents) {
|
|
767
|
-
[self setSheetAllowedDetents:[RNSConvert
|
|
1144
|
+
[self setSheetAllowedDetents:[RNSConvert detentFractionsArrayFromVector:newScreenProps.sheetAllowedDetents]];
|
|
768
1145
|
}
|
|
769
1146
|
|
|
770
1147
|
if (newScreenProps.sheetLargestUndimmedDetent != oldScreenProps.sheetLargestUndimmedDetent) {
|
|
771
|
-
[self setSheetLargestUndimmedDetent:
|
|
772
|
-
[RNSConvert RNSScreenDetentTypeFromLargestUndimmedDetent:newScreenProps.sheetLargestUndimmedDetent]];
|
|
1148
|
+
[self setSheetLargestUndimmedDetent:[NSNumber numberWithInt:newScreenProps.sheetLargestUndimmedDetent]];
|
|
773
1149
|
}
|
|
774
1150
|
#endif // !TARGET_OS_TV
|
|
775
1151
|
|
|
@@ -816,7 +1192,7 @@ namespace react = facebook::react;
|
|
|
816
1192
|
{
|
|
817
1193
|
[super finalizeUpdates:updateMask];
|
|
818
1194
|
#if !TARGET_OS_TV && !TARGET_OS_VISION
|
|
819
|
-
[self
|
|
1195
|
+
[self updateFormSheetPresentationStyle];
|
|
820
1196
|
#endif // !TARGET_OS_TV
|
|
821
1197
|
}
|
|
822
1198
|
|
|
@@ -827,7 +1203,9 @@ namespace react = facebook::react;
|
|
|
827
1203
|
{
|
|
828
1204
|
[super didSetProps:changedProps];
|
|
829
1205
|
#if !TARGET_OS_TV && !TARGET_OS_VISION
|
|
830
|
-
|
|
1206
|
+
if (self.stackPresentation == RNSScreenStackPresentationFormSheet) {
|
|
1207
|
+
[self updateFormSheetPresentationStyle];
|
|
1208
|
+
}
|
|
831
1209
|
#endif // !TARGET_OS_TV
|
|
832
1210
|
}
|
|
833
1211
|
|
|
@@ -855,6 +1233,7 @@ namespace react = facebook::react;
|
|
|
855
1233
|
- (void)invalidate
|
|
856
1234
|
{
|
|
857
1235
|
_controller = nil;
|
|
1236
|
+
[_sheetsScrollView removeObserver:self forKeyPath:@"bounds" context:nil];
|
|
858
1237
|
}
|
|
859
1238
|
#endif
|
|
860
1239
|
|
|
@@ -1465,6 +1844,7 @@ RCT_EXPORT_VIEW_PROPERTY(onTransitionProgress, RCTDirectEventBlock);
|
|
|
1465
1844
|
RCT_EXPORT_VIEW_PROPERTY(onWillAppear, RCTDirectEventBlock);
|
|
1466
1845
|
RCT_EXPORT_VIEW_PROPERTY(onWillDisappear, RCTDirectEventBlock);
|
|
1467
1846
|
RCT_EXPORT_VIEW_PROPERTY(onGestureCancel, RCTDirectEventBlock);
|
|
1847
|
+
RCT_EXPORT_VIEW_PROPERTY(onSheetDetentChanged, RCTDirectEventBlock);
|
|
1468
1848
|
|
|
1469
1849
|
#if !TARGET_OS_TV
|
|
1470
1850
|
RCT_EXPORT_VIEW_PROPERTY(screenOrientation, UIInterfaceOrientationMask)
|
|
@@ -1473,8 +1853,8 @@ RCT_EXPORT_VIEW_PROPERTY(statusBarHidden, BOOL)
|
|
|
1473
1853
|
RCT_EXPORT_VIEW_PROPERTY(statusBarStyle, RNSStatusBarStyle)
|
|
1474
1854
|
RCT_EXPORT_VIEW_PROPERTY(homeIndicatorHidden, BOOL)
|
|
1475
1855
|
|
|
1476
|
-
RCT_EXPORT_VIEW_PROPERTY(sheetAllowedDetents,
|
|
1477
|
-
RCT_EXPORT_VIEW_PROPERTY(sheetLargestUndimmedDetent,
|
|
1856
|
+
RCT_EXPORT_VIEW_PROPERTY(sheetAllowedDetents, NSArray<NSNumber *> *);
|
|
1857
|
+
RCT_EXPORT_VIEW_PROPERTY(sheetLargestUndimmedDetent, NSNumber *);
|
|
1478
1858
|
RCT_EXPORT_VIEW_PROPERTY(sheetGrabberVisible, BOOL);
|
|
1479
1859
|
RCT_EXPORT_VIEW_PROPERTY(sheetCornerRadius, CGFloat);
|
|
1480
1860
|
RCT_EXPORT_VIEW_PROPERTY(sheetExpandsWhenScrolledToEdge, BOOL);
|
|
@@ -1629,3 +2009,7 @@ RCT_ENUM_CONVERTER(
|
|
|
1629
2009
|
#endif
|
|
1630
2010
|
|
|
1631
2011
|
@end
|
|
2012
|
+
|
|
2013
|
+
// So that the define-macro is not leaked out of this file.
|
|
2014
|
+
// This one is defined in very top of the file depending on RN architecture.
|
|
2015
|
+
#undef ReactScrollViewBase
|