@lodev09/react-native-true-sheet 4.0.0-beta.3 → 4.0.0-beta.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -5
- package/android/build.gradle +23 -1
- package/android/proguard-rules.pro +3 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetContainerView.kt +50 -16
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetContentView.kt +303 -184
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetContentViewManager.kt +5 -1
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetFooterView.kt +38 -109
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetModule.kt +13 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetOverlayView.kt +127 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetOverlayViewManager.kt +45 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetPackage.kt +2 -1
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetStateUpdater.kt +29 -3
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetView.kt +234 -66
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewController.kt +491 -186
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewManager.kt +64 -10
- package/android/src/main/java/com/lodev09/truesheet/core/RNScreensEventObserver.kt +31 -14
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetBottomSheetBehavior.kt +135 -0
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetBottomSheetView.kt +23 -23
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetCoordinatorLayout.kt +130 -6
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetDetentCalculator.kt +104 -39
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetDimView.kt +14 -17
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetGrabberView.kt +2 -4
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetOverlayRootView.kt +148 -0
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetStackManager.kt +33 -40
- package/android/src/main/java/com/lodev09/truesheet/events/TrueSheetLifecycleEvents.kt +15 -0
- package/android/src/main/java/com/lodev09/truesheet/utils/ColorUtils.kt +19 -0
- package/android/src/main/java/com/lodev09/truesheet/utils/KeyboardUtils.kt +15 -2
- package/android/src/main/java/com/lodev09/truesheet/utils/ScreenUtils.kt +0 -12
- package/android/src/main/java/com/lodev09/truesheet/utils/ViewUtils.kt +19 -7
- package/android/src/main/jni/TrueSheetSpec.h +1 -0
- package/android/src/main/jni/TrueSheetStateUpdater.cpp +37 -6
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewComponentDescriptor.h +1 -9
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewShadowNode.cpp +114 -30
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewShadowNode.h +30 -7
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewState.cpp +2 -2
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewState.h +9 -8
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewComponentDescriptor.h +3 -5
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewShadowNode.cpp +14 -3
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewShadowNode.h +5 -6
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewState.cpp +1 -1
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewState.h +10 -6
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetInsets.cpp +1 -1
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetInsets.h +1 -1
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetLayoutUtils.h +43 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetOverlayViewComponentDescriptor.h +21 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetOverlayViewShadowNode.cpp +17 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetOverlayViewShadowNode.h +33 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewComponentDescriptor.h +3 -5
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewShadowNode.cpp +7 -40
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewShadowNode.h +3 -7
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewState.cpp +3 -5
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewState.h +4 -5
- package/ios/TrueSheetContainerView.h +23 -7
- package/ios/TrueSheetContainerView.mm +45 -25
- package/ios/TrueSheetContentView.h +44 -15
- package/ios/TrueSheetContentView.mm +221 -190
- package/ios/TrueSheetFooterView.mm +133 -28
- package/ios/TrueSheetModule.h +2 -7
- package/ios/TrueSheetModule.mm +18 -18
- package/ios/TrueSheetOverlayView.h +42 -0
- package/ios/TrueSheetOverlayView.mm +175 -0
- package/ios/TrueSheetView.h +2 -0
- package/ios/TrueSheetView.mm +268 -52
- package/ios/TrueSheetViewController.h +36 -3
- package/ios/TrueSheetViewController.mm +797 -102
- package/ios/core/RNScreensEventObserver.mm +31 -28
- package/ios/core/TrueSheetBlurView.h +0 -2
- package/ios/core/TrueSheetBlurView.mm +3 -36
- package/ios/core/TrueSheetDetentCalculator.h +18 -1
- package/ios/core/TrueSheetDetentCalculator.mm +44 -9
- package/ios/core/TrueSheetDimView.h +27 -0
- package/ios/core/TrueSheetDimView.mm +41 -0
- package/ios/core/TrueSheetGrabberView.mm +13 -3
- package/ios/core/TrueSheetKeyboardObserver.h +7 -0
- package/ios/core/TrueSheetKeyboardObserver.mm +107 -15
- package/ios/core/TrueSheetOverlayContainerView.h +31 -0
- package/ios/core/TrueSheetOverlayContainerView.mm +35 -0
- package/ios/events/TrueSheetLifecycleEvents.h +2 -0
- package/ios/events/TrueSheetLifecycleEvents.mm +8 -0
- package/ios/tvos/TrueSheetStubs.mm +12 -0
- package/ios/utils/UIView+ScrollEdgeInteraction.h +1 -0
- package/ios/utils/UIView+ScrollEdgeInteraction.mm +24 -2
- package/lib/module/TrueSheet.js +222 -54
- package/lib/module/TrueSheet.js.map +1 -1
- package/lib/module/TrueSheet.web.js +364 -275
- package/lib/module/TrueSheet.web.js.map +1 -1
- package/lib/module/TrueSheetBackground.js +15 -0
- package/lib/module/TrueSheetBackground.js.map +1 -0
- package/lib/module/TrueSheetOverlay.js +30 -0
- package/lib/module/TrueSheetOverlay.js.map +1 -0
- package/lib/module/TrueSheetOverlay.web.js +35 -0
- package/lib/module/TrueSheetOverlay.web.js.map +1 -0
- package/lib/module/TrueSheetPeek.web.js +20 -15
- package/lib/module/TrueSheetPeek.web.js.map +1 -1
- package/lib/module/TrueSheetProvider.web.js +13 -9
- package/lib/module/TrueSheetProvider.web.js.map +1 -1
- package/lib/module/detentBackgrounds.js +21 -0
- package/lib/module/detentBackgrounds.js.map +1 -0
- package/lib/module/fabric/TrueSheetContentViewNativeComponent.ts +1 -1
- package/lib/module/fabric/TrueSheetFooterViewNativeComponent.ts +2 -3
- package/lib/module/fabric/TrueSheetOverlayViewNativeComponent.ts +12 -0
- package/lib/module/fabric/TrueSheetViewNativeComponent.ts +89 -73
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/mocks/index.js +18 -2
- package/lib/module/mocks/index.js.map +1 -1
- package/lib/module/mocks/navigationExpoRouter.js.map +1 -1
- package/lib/module/navigation/base-types.js +2 -0
- package/lib/module/navigation/base-types.js.map +1 -0
- package/lib/module/navigation/createTrueSheetRouter.js +158 -100
- package/lib/module/navigation/createTrueSheetRouter.js.map +1 -1
- package/lib/module/navigation/expo-router/base-types.js +2 -0
- package/lib/module/navigation/expo-router/base-types.js.map +1 -0
- package/lib/module/navigation/expo-router/extendTrueSheetRouter.js +71 -0
- package/lib/module/navigation/expo-router/extendTrueSheetRouter.js.map +1 -0
- package/lib/module/navigation/expo-router/index.js +18 -7
- package/lib/module/navigation/expo-router/index.js.map +1 -1
- package/lib/module/navigation/expo-router/types.js +4 -0
- package/lib/module/navigation/expo-router/types.js.map +1 -0
- package/lib/module/navigation/index.js.map +1 -1
- package/lib/module/navigation/screen/useSheetScreenState.js +1 -0
- package/lib/module/navigation/screen/useSheetScreenState.js.map +1 -1
- package/lib/module/scrollable.js +28 -0
- package/lib/module/scrollable.js.map +1 -0
- package/lib/module/web/constants.js +1 -1
- package/lib/module/web/constants.js.map +1 -1
- package/lib/module/web/keyboard.js +69 -0
- package/lib/module/web/keyboard.js.map +1 -0
- package/lib/module/web/layout.js +168 -0
- package/lib/module/web/layout.js.map +1 -0
- package/lib/module/web/vaul/constants.js +9 -0
- package/lib/module/web/vaul/constants.js.map +1 -1
- package/lib/module/web/vaul/context.js +4 -0
- package/lib/module/web/vaul/context.js.map +1 -1
- package/lib/module/web/vaul/helpers.js +1 -0
- package/lib/module/web/vaul/helpers.js.map +1 -1
- package/lib/module/web/vaul/index.js +83 -21
- package/lib/module/web/vaul/index.js.map +1 -1
- package/lib/module/web/vaul/use-snap-points.js +57 -28
- package/lib/module/web/vaul/use-snap-points.js.map +1 -1
- package/lib/typescript/src/TrueSheet.d.ts +18 -1
- package/lib/typescript/src/TrueSheet.d.ts.map +1 -1
- package/lib/typescript/src/TrueSheet.types.d.ts +209 -35
- package/lib/typescript/src/TrueSheet.types.d.ts.map +1 -1
- package/lib/typescript/src/TrueSheet.web.d.ts.map +1 -1
- package/lib/typescript/src/TrueSheetBackground.d.ts +3 -0
- package/lib/typescript/src/TrueSheetBackground.d.ts.map +1 -0
- package/lib/typescript/src/TrueSheetOverlay.d.ts +8 -0
- package/lib/typescript/src/TrueSheetOverlay.d.ts.map +1 -0
- package/lib/typescript/src/TrueSheetOverlay.web.d.ts +8 -0
- package/lib/typescript/src/TrueSheetOverlay.web.d.ts.map +1 -0
- package/lib/typescript/src/TrueSheetPeek.web.d.ts +8 -4
- package/lib/typescript/src/TrueSheetPeek.web.d.ts.map +1 -1
- package/lib/typescript/src/TrueSheetProvider.web.d.ts +5 -1
- package/lib/typescript/src/TrueSheetProvider.web.d.ts.map +1 -1
- package/lib/typescript/src/detentBackgrounds.d.ts +10 -0
- package/lib/typescript/src/detentBackgrounds.d.ts.map +1 -0
- package/lib/typescript/src/fabric/TrueSheetFooterViewNativeComponent.d.ts +2 -3
- package/lib/typescript/src/fabric/TrueSheetFooterViewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/fabric/TrueSheetOverlayViewNativeComponent.d.ts +6 -0
- package/lib/typescript/src/fabric/TrueSheetOverlayViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/fabric/TrueSheetViewNativeComponent.d.ts +76 -65
- package/lib/typescript/src/fabric/TrueSheetViewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +1 -0
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/mocks/index.d.ts +4 -0
- package/lib/typescript/src/mocks/index.d.ts.map +1 -1
- package/lib/typescript/src/mocks/navigationExpoRouter.d.ts +3 -3
- package/lib/typescript/src/mocks/navigationExpoRouter.d.ts.map +1 -1
- package/lib/typescript/src/navigation/base-types.d.ts +9 -0
- package/lib/typescript/src/navigation/base-types.d.ts.map +1 -0
- package/lib/typescript/src/navigation/createTrueSheetRouter.d.ts +36 -10
- package/lib/typescript/src/navigation/createTrueSheetRouter.d.ts.map +1 -1
- package/lib/typescript/src/navigation/expo-router/base-types.d.ts +8 -0
- package/lib/typescript/src/navigation/expo-router/base-types.d.ts.map +1 -0
- package/lib/typescript/src/navigation/expo-router/extendTrueSheetRouter.d.ts +33 -0
- package/lib/typescript/src/navigation/expo-router/extendTrueSheetRouter.d.ts.map +1 -0
- package/lib/typescript/src/navigation/expo-router/index.d.ts +9 -6
- package/lib/typescript/src/navigation/expo-router/index.d.ts.map +1 -1
- package/lib/typescript/src/navigation/expo-router/types.d.ts +44 -0
- package/lib/typescript/src/navigation/expo-router/types.d.ts.map +1 -0
- package/lib/typescript/src/navigation/index.d.ts +3 -4
- package/lib/typescript/src/navigation/index.d.ts.map +1 -1
- package/lib/typescript/src/navigation/screen/useSheetScreenState.d.ts +2 -1
- package/lib/typescript/src/navigation/screen/useSheetScreenState.d.ts.map +1 -1
- package/lib/typescript/src/navigation/types.d.ts +43 -6
- package/lib/typescript/src/navigation/types.d.ts.map +1 -1
- package/lib/typescript/src/scrollable.d.ts +2 -0
- package/lib/typescript/src/scrollable.d.ts.map +1 -0
- package/lib/typescript/src/web/constants.d.ts +1 -1
- package/lib/typescript/src/web/constants.d.ts.map +1 -1
- package/lib/typescript/src/web/keyboard.d.ts +15 -0
- package/lib/typescript/src/web/keyboard.d.ts.map +1 -0
- package/lib/typescript/src/web/layout.d.ts +20 -0
- package/lib/typescript/src/web/layout.d.ts.map +1 -0
- package/lib/typescript/src/web/vaul/constants.d.ts +3 -0
- package/lib/typescript/src/web/vaul/constants.d.ts.map +1 -1
- package/lib/typescript/src/web/vaul/context.d.ts +5 -1
- package/lib/typescript/src/web/vaul/context.d.ts.map +1 -1
- package/lib/typescript/src/web/vaul/helpers.d.ts +1 -0
- package/lib/typescript/src/web/vaul/helpers.d.ts.map +1 -1
- package/lib/typescript/src/web/vaul/index.d.ts +20 -1
- package/lib/typescript/src/web/vaul/index.d.ts.map +1 -1
- package/lib/typescript/src/web/vaul/types.d.ts +9 -0
- package/lib/typescript/src/web/vaul/types.d.ts.map +1 -1
- package/lib/typescript/src/web/vaul/use-snap-points.d.ts +6 -4
- package/lib/typescript/src/web/vaul/use-snap-points.d.ts.map +1 -1
- package/package.json +18 -8
- package/react-native.config.js +1 -0
- package/src/TrueSheet.tsx +257 -62
- package/src/TrueSheet.types.ts +225 -35
- package/src/TrueSheet.web.tsx +445 -333
- package/src/TrueSheetBackground.tsx +17 -0
- package/src/TrueSheetOverlay.tsx +24 -0
- package/src/TrueSheetOverlay.web.tsx +33 -0
- package/src/TrueSheetPeek.web.tsx +25 -23
- package/src/TrueSheetProvider.web.tsx +22 -13
- package/src/detentBackgrounds.ts +24 -0
- package/src/fabric/TrueSheetContentViewNativeComponent.ts +1 -1
- package/src/fabric/TrueSheetFooterViewNativeComponent.ts +2 -3
- package/src/fabric/TrueSheetOverlayViewNativeComponent.ts +12 -0
- package/src/fabric/TrueSheetViewNativeComponent.ts +89 -73
- package/src/index.ts +1 -0
- package/src/mocks/index.ts +17 -2
- package/src/mocks/navigationExpoRouter.ts +6 -5
- package/src/navigation/base-types.ts +20 -0
- package/src/navigation/createTrueSheetRouter.ts +220 -144
- package/src/navigation/expo-router/base-types.ts +18 -0
- package/src/navigation/expo-router/extendTrueSheetRouter.ts +99 -0
- package/src/navigation/expo-router/index.ts +41 -30
- package/src/navigation/expo-router/types.ts +116 -0
- package/src/navigation/index.ts +6 -7
- package/src/navigation/screen/useSheetScreenState.ts +2 -0
- package/src/navigation/types.ts +81 -23
- package/src/scrollable.ts +25 -0
- package/src/web/constants.ts +1 -1
- package/src/web/keyboard.ts +79 -0
- package/src/web/layout.ts +196 -0
- package/src/web/vaul/constants.ts +9 -0
- package/src/web/vaul/context.ts +7 -1
- package/src/web/vaul/helpers.ts +5 -0
- package/src/web/vaul/index.tsx +113 -16
- package/src/web/vaul/types.ts +10 -0
- package/src/web/vaul/use-snap-points.ts +86 -33
|
@@ -67,7 +67,7 @@ using namespace facebook::react;
|
|
|
67
67
|
return;
|
|
68
68
|
}
|
|
69
69
|
_bottomInset = bottomInset;
|
|
70
|
-
[self
|
|
70
|
+
[self pushStateWithMode:EventQueue::UpdateMode::unstable_Immediate];
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
// Skipped while the keyboard is open — an absolute footer rises above the
|
|
@@ -77,22 +77,36 @@ using namespace facebook::react;
|
|
|
77
77
|
return;
|
|
78
78
|
}
|
|
79
79
|
_keyboardVisible = keyboardVisible;
|
|
80
|
-
[self
|
|
80
|
+
[self pushStateWithMode:EventQueue::UpdateMode::unstable_Immediate];
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
-
|
|
83
|
+
// The keyboard slide is a transform the shadow tree can't see — mirror it so
|
|
84
|
+
// measure() (and Pressability's press region) match where the footer is drawn.
|
|
85
|
+
// Async: no layout reads it.
|
|
86
|
+
- (void)setKeyboardOffset:(CGFloat)keyboardOffset {
|
|
87
|
+
if (_currentKeyboardOffset == keyboardOffset) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
_currentKeyboardOffset = keyboardOffset;
|
|
91
|
+
[self pushStateWithMode:EventQueue::UpdateMode::Asynchronous];
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Every push carries all fields — RN's EventQueue drops a still-queued update
|
|
95
|
+
// for the same view when the next one is enqueued.
|
|
96
|
+
- (void)pushStateWithMode:(EventQueue::UpdateMode)mode {
|
|
84
97
|
if (!_state) {
|
|
85
98
|
return;
|
|
86
99
|
}
|
|
87
100
|
|
|
88
101
|
TrueSheetFooterViewState newState;
|
|
89
102
|
newState.bottomInset = _keyboardVisible ? 0 : _bottomInset;
|
|
103
|
+
newState.translateY = -_currentKeyboardOffset;
|
|
90
104
|
newState.initialized = true;
|
|
91
|
-
// Immediate so
|
|
92
|
-
// the async path races the keyboard caret scroll and
|
|
93
|
-
// them an inset stale (same reason Android bridges
|
|
94
|
-
// TrueSheetStateUpdater).
|
|
95
|
-
_state->updateState(std::move(newState),
|
|
105
|
+
// Inset changes go Immediate so they land before anything reads the
|
|
106
|
+
// footer's height — the async path races the keyboard caret scroll and
|
|
107
|
+
// detent setup, leaving them an inset stale (same reason Android bridges
|
|
108
|
+
// through TrueSheetStateUpdater).
|
|
109
|
+
_state->updateState(std::move(newState), mode);
|
|
96
110
|
_didPushBottomInset = YES;
|
|
97
111
|
}
|
|
98
112
|
|
|
@@ -123,6 +137,11 @@ using namespace facebook::react;
|
|
|
123
137
|
|
|
124
138
|
- (void)collectAccessibilityElementsFromView:(UIView *)view into:(NSMutableArray *)elements {
|
|
125
139
|
for (UIView *subview in view.subviews) {
|
|
140
|
+
// Fabric hides `display: none` views instead of unmounting them
|
|
141
|
+
if (subview.hidden) {
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
|
|
126
145
|
if (subview.isAccessibilityElement || subview.accessibilityLabel || subview.accessibilityIdentifier) {
|
|
127
146
|
[elements addObject:subview];
|
|
128
147
|
} else if (subview.accessibilityElements.count > 0) {
|
|
@@ -137,7 +156,19 @@ using namespace facebook::react;
|
|
|
137
156
|
|
|
138
157
|
- (void)updateLayoutMetrics:(const facebook::react::LayoutMetrics &)layoutMetrics
|
|
139
158
|
oldLayoutMetrics:(const facebook::react::LayoutMetrics &)oldLayoutMetrics {
|
|
140
|
-
|
|
159
|
+
// UIKit resizes the sheet for the keyboard inside its animation, and the new
|
|
160
|
+
// size usually relays out the footer in the same pass. When the keyboard
|
|
161
|
+
// changes during a React commit (e.g. its input unmounts), that layout can
|
|
162
|
+
// only mount after the commit, outside the animation — the footer, pinned to
|
|
163
|
+
// the container's bottom edge, would snap by the keyboard's height while the
|
|
164
|
+
// sheet is still animating. Carry it on the rest of the keyboard's curve.
|
|
165
|
+
if (layoutMetrics.frame.origin.y != oldLayoutMetrics.frame.origin.y) {
|
|
166
|
+
[self animateAlongKeyboard:^{
|
|
167
|
+
[super updateLayoutMetrics:layoutMetrics oldLayoutMetrics:oldLayoutMetrics];
|
|
168
|
+
}];
|
|
169
|
+
} else {
|
|
170
|
+
[super updateLayoutMetrics:layoutMetrics oldLayoutMetrics:oldLayoutMetrics];
|
|
171
|
+
}
|
|
141
172
|
|
|
142
173
|
// State lands before layout metrics within the same mount transaction, so
|
|
143
174
|
// this reflects the inset the shadow node baked into this frame — seeded
|
|
@@ -155,6 +186,8 @@ using namespace facebook::react;
|
|
|
155
186
|
_lastHeight = height;
|
|
156
187
|
[self.delegate footerViewDidChangeSize:CGSizeMake(layoutMetrics.frame.size.width, height)];
|
|
157
188
|
}
|
|
189
|
+
|
|
190
|
+
[self applyKeyboardOffset];
|
|
158
191
|
}
|
|
159
192
|
|
|
160
193
|
- (void)prepareForRecycle {
|
|
@@ -176,55 +209,127 @@ using namespace facebook::react;
|
|
|
176
209
|
|
|
177
210
|
#pragma mark - TrueSheetKeyboardObserverDelegate
|
|
178
211
|
|
|
212
|
+
- (void)setKeyboardObserver:(TrueSheetKeyboardObserver *)keyboardObserver {
|
|
213
|
+
[_keyboardObserver removeDelegate:self];
|
|
214
|
+
_keyboardObserver = keyboardObserver;
|
|
215
|
+
[keyboardObserver addDelegate:self];
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
- (void)animateAlongKeyboard:(void (^)(void))changes {
|
|
219
|
+
NSTimeInterval remaining = self.keyboardObserver.remainingAnimationDuration;
|
|
220
|
+
if (remaining > 0 && [UIView inheritedAnimationDuration] == 0) {
|
|
221
|
+
[UIView animateWithDuration:remaining
|
|
222
|
+
delay:0
|
|
223
|
+
options:self.keyboardObserver.animationCurve | UIViewAnimationOptionBeginFromCurrentState
|
|
224
|
+
animations:^{
|
|
225
|
+
changes();
|
|
226
|
+
[self syncEdgeEffect];
|
|
227
|
+
}
|
|
228
|
+
completion:nil];
|
|
229
|
+
} else {
|
|
230
|
+
changes();
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// Only an absolute footer floats above the keyboard — a relative footer stays
|
|
235
|
+
// in the layout flow behind it, and an absolute one opts out via
|
|
236
|
+
// footerOptions.avoidKeyboard.
|
|
237
|
+
- (BOOL)floatsAboveKeyboard {
|
|
238
|
+
TrueSheetViewController *controller = self.keyboardObserver.viewController;
|
|
239
|
+
return controller.absoluteFooter && controller.footerAvoidsKeyboard;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
- (CGFloat)keyboardSlideForHeight:(CGFloat)height {
|
|
243
|
+
UIWindow *window = self.window;
|
|
244
|
+
if (!window) {
|
|
245
|
+
return 0;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// Measure in the transform's coordinate space, excluding the footer's current slide.
|
|
249
|
+
CGFloat footerBottom = self.center.y + self.bounds.size.height / 2;
|
|
250
|
+
CGPoint keyboardTopInWindow = CGPointMake(CGRectGetMidX(window.bounds), CGRectGetMaxY(window.bounds) - height);
|
|
251
|
+
CGFloat keyboardTop = [self.superview convertPoint:keyboardTopInWindow fromView:window].y;
|
|
252
|
+
CGFloat keyboardOffset = self.keyboardObserver.viewController.footerKeyboardOffset;
|
|
253
|
+
return MAX(0, footerBottom - keyboardTop + keyboardOffset);
|
|
254
|
+
}
|
|
255
|
+
|
|
179
256
|
// Yoga owns the footer's frame (pinned to the container's bottom edge), so the
|
|
180
|
-
// keyboard slide is carried by a transform instead of layout.
|
|
181
|
-
// footer floats above the keyboard — a relative footer stays in the layout
|
|
182
|
-
// flow behind it.
|
|
257
|
+
// keyboard slide is carried by a transform instead of layout.
|
|
183
258
|
- (void)keyboardWillShow:(CGFloat)height duration:(NSTimeInterval)duration curve:(UIViewAnimationOptions)curve {
|
|
184
|
-
if (!self
|
|
259
|
+
if (![self floatsAboveKeyboard]) {
|
|
185
260
|
return;
|
|
186
261
|
}
|
|
187
262
|
|
|
188
263
|
[self setKeyboardVisible:YES];
|
|
189
264
|
|
|
190
|
-
CGFloat
|
|
191
|
-
|
|
192
|
-
_currentKeyboardOffset = slide;
|
|
265
|
+
CGFloat slide = [self keyboardSlideForHeight:height];
|
|
266
|
+
[self setKeyboardOffset:slide];
|
|
193
267
|
|
|
194
268
|
[UIView animateWithDuration:duration
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
269
|
+
delay:0
|
|
270
|
+
options:curve | UIViewAnimationOptionBeginFromCurrentState
|
|
271
|
+
animations:^{
|
|
272
|
+
self.transform = CGAffineTransformMakeTranslation(0, -slide);
|
|
273
|
+
[self syncEdgeEffect];
|
|
274
|
+
}
|
|
275
|
+
completion:^(BOOL finished) {
|
|
276
|
+
[self applyKeyboardOffset];
|
|
277
|
+
}];
|
|
201
278
|
}
|
|
202
279
|
|
|
203
280
|
- (void)keyboardWillHide:(NSTimeInterval)duration curve:(UIViewAnimationOptions)curve {
|
|
281
|
+
// Offset first — the visible push replaces it in the queue, one commit
|
|
282
|
+
[self setKeyboardOffset:0];
|
|
204
283
|
[self setKeyboardVisible:NO];
|
|
205
|
-
_currentKeyboardOffset = 0;
|
|
206
284
|
|
|
207
285
|
[UIView animateWithDuration:duration
|
|
208
286
|
delay:0
|
|
209
287
|
options:curve | UIViewAnimationOptionBeginFromCurrentState
|
|
210
288
|
animations:^{
|
|
211
289
|
self.transform = CGAffineTransformIdentity;
|
|
290
|
+
[self syncEdgeEffect];
|
|
212
291
|
}
|
|
213
292
|
completion:nil];
|
|
214
293
|
}
|
|
215
294
|
|
|
295
|
+
// UIKit derives the edge effect region from model geometry at commit time,
|
|
296
|
+
// outside our animation context — the blur snaps to the footer's final
|
|
297
|
+
// position while the footer is still animating. Re-evaluating the scroll
|
|
298
|
+
// view's layout inside the animation block makes the region change inherit
|
|
299
|
+
// the keyboard curve.
|
|
300
|
+
- (void)syncEdgeEffect {
|
|
301
|
+
if (@available(iOS 26.0, *)) {
|
|
302
|
+
UIScrollView *scrollView = [self edgeInteractionScrollView];
|
|
303
|
+
if (scrollView) {
|
|
304
|
+
[scrollView setNeedsLayout];
|
|
305
|
+
[scrollView layoutIfNeeded];
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
216
310
|
- (void)applyKeyboardOffset {
|
|
217
311
|
CGFloat height = self.keyboardObserver.currentHeight;
|
|
218
|
-
if (height <= 0
|
|
312
|
+
if (height <= 0) {
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// avoidKeyboard flipped off mid-keyboard — drop the slide already applied
|
|
317
|
+
if (![self floatsAboveKeyboard]) {
|
|
318
|
+
[self setKeyboardOffset:0];
|
|
319
|
+
[self setKeyboardVisible:NO];
|
|
320
|
+
self.transform = CGAffineTransformIdentity;
|
|
219
321
|
return;
|
|
220
322
|
}
|
|
221
323
|
|
|
222
324
|
[self setKeyboardVisible:YES];
|
|
223
325
|
|
|
224
|
-
CGFloat
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
326
|
+
CGFloat slide = [self keyboardSlideForHeight:height];
|
|
327
|
+
[self setKeyboardOffset:slide];
|
|
328
|
+
// A footer mounted or relaid out mid-keyboard animation follows the keyboard
|
|
329
|
+
// instead of snapping ahead of it
|
|
330
|
+
[self animateAlongKeyboard:^{
|
|
331
|
+
self.transform = CGAffineTransformMakeTranslation(0, -slide);
|
|
332
|
+
}];
|
|
228
333
|
}
|
|
229
334
|
|
|
230
335
|
@end
|
package/ios/TrueSheetModule.h
CHANGED
|
@@ -27,16 +27,11 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
29
|
* Register a sheet component view with its React tag
|
|
30
|
-
* Called automatically by TrueSheetView
|
|
30
|
+
* Called automatically by TrueSheetView when it attaches to a window.
|
|
31
|
+
* The registry holds views weakly, so no unregistration is needed.
|
|
31
32
|
*/
|
|
32
33
|
+ (void)registerView:(TrueSheetView *)view withTag:(NSNumber *)tag;
|
|
33
34
|
|
|
34
|
-
/**
|
|
35
|
-
* Unregister a sheet component view
|
|
36
|
-
* Called automatically by TrueSheetView during dealloc
|
|
37
|
-
*/
|
|
38
|
-
+ (void)unregisterViewWithTag:(NSNumber *)tag;
|
|
39
|
-
|
|
40
35
|
@end
|
|
41
36
|
|
|
42
37
|
NS_ASSUME_NONNULL_END
|
package/ios/TrueSheetModule.mm
CHANGED
|
@@ -18,8 +18,9 @@
|
|
|
18
18
|
|
|
19
19
|
#import <TrueSheetSpec/TrueSheetSpec.h>
|
|
20
20
|
|
|
21
|
-
// Static registry
|
|
22
|
-
|
|
21
|
+
// Static registry of live hosts by tag — weak so an unmounted host deallocates
|
|
22
|
+
// (RN zeroes the tag before teardown, so hosts can't unregister themselves)
|
|
23
|
+
static NSMapTable<NSNumber *, TrueSheetView *> *viewRegistry;
|
|
23
24
|
|
|
24
25
|
@interface TrueSheetModule () <NativeTrueSheetModuleSpec>
|
|
25
26
|
@end
|
|
@@ -30,7 +31,7 @@ RCT_EXPORT_MODULE(TrueSheetModule)
|
|
|
30
31
|
|
|
31
32
|
+ (void)initialize {
|
|
32
33
|
if (self == [TrueSheetModule class]) {
|
|
33
|
-
viewRegistry = [
|
|
34
|
+
viewRegistry = [NSMapTable strongToWeakObjectsMapTable];
|
|
34
35
|
}
|
|
35
36
|
}
|
|
36
37
|
|
|
@@ -148,11 +149,17 @@ RCT_EXPORT_MODULE(TrueSheetModule)
|
|
|
148
149
|
- (void)dismissAll:(BOOL)animated resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
|
|
149
150
|
RCTExecuteOnMainQueue(^{
|
|
150
151
|
@synchronized(viewRegistry) {
|
|
152
|
+
// Drop presents still waiting on another sheet's dismissal
|
|
153
|
+
for (TrueSheetView *view in viewRegistry.objectEnumerator) {
|
|
154
|
+
[view cancelPendingPresent];
|
|
155
|
+
}
|
|
156
|
+
|
|
151
157
|
// Find the root presented sheet (one without a parent TrueSheet)
|
|
152
158
|
TrueSheetView *rootSheet = nil;
|
|
153
159
|
|
|
154
|
-
for (TrueSheetView *view in viewRegistry.
|
|
155
|
-
|
|
160
|
+
for (TrueSheetView *view in viewRegistry.objectEnumerator) {
|
|
161
|
+
// A sheet still animating in counts too — dismissAnimated waits for it to land
|
|
162
|
+
if (!view.viewController.isPresented && !view.viewController.isBeingPresented) {
|
|
156
163
|
continue;
|
|
157
164
|
}
|
|
158
165
|
|
|
@@ -170,7 +177,10 @@ RCT_EXPORT_MODULE(TrueSheetModule)
|
|
|
170
177
|
return;
|
|
171
178
|
}
|
|
172
179
|
|
|
173
|
-
|
|
180
|
+
// Mid-present, the deferred dismiss tracks its own position like a regular dismiss
|
|
181
|
+
if (rootSheet.viewController.isPresented) {
|
|
182
|
+
[rootSheet emitDismissedPosition];
|
|
183
|
+
}
|
|
174
184
|
[rootSheet dismissAnimated:animated
|
|
175
185
|
completion:^(BOOL success, NSError *_Nullable error) {
|
|
176
186
|
if (success) {
|
|
@@ -191,7 +201,7 @@ RCT_EXPORT_MODULE(TrueSheetModule)
|
|
|
191
201
|
}
|
|
192
202
|
|
|
193
203
|
@synchronized(viewRegistry) {
|
|
194
|
-
return viewRegistry
|
|
204
|
+
return [viewRegistry objectForKey:reactTag];
|
|
195
205
|
}
|
|
196
206
|
}
|
|
197
207
|
|
|
@@ -201,17 +211,7 @@ RCT_EXPORT_MODULE(TrueSheetModule)
|
|
|
201
211
|
}
|
|
202
212
|
|
|
203
213
|
@synchronized(viewRegistry) {
|
|
204
|
-
viewRegistry
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
+ (void)unregisterViewWithTag:(NSNumber *)tag {
|
|
209
|
-
if (!tag) {
|
|
210
|
-
return;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
@synchronized(viewRegistry) {
|
|
214
|
-
[viewRegistry removeObjectForKey:tag];
|
|
214
|
+
[viewRegistry setObject:view forKey:tag];
|
|
215
215
|
}
|
|
216
216
|
}
|
|
217
217
|
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Created by Jovanni Lo (@lodev09)
|
|
3
|
+
// Copyright (c) 2024-present. All rights reserved.
|
|
4
|
+
//
|
|
5
|
+
// This source code is licensed under the MIT license found in the
|
|
6
|
+
// LICENSE file in the root directory of this source tree.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
10
|
+
|
|
11
|
+
#import <React/RCTViewComponentView.h>
|
|
12
|
+
#import <UIKit/UIKit.h>
|
|
13
|
+
|
|
14
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Posted when an overlay container joins or leaves a window.
|
|
18
|
+
*/
|
|
19
|
+
extern NSNotificationName const TrueSheetOverlayWindowDidChangeNotification;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Hidden host that renders its children in a container attached directly to
|
|
23
|
+
* the window, above every presented sheet.
|
|
24
|
+
*/
|
|
25
|
+
@interface TrueSheetOverlayView : RCTViewComponentView
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Re-stacks every overlay container above the window's other subviews.
|
|
29
|
+
* Called when a sheet presents, since presenting adds its transition view on top.
|
|
30
|
+
*/
|
|
31
|
+
+ (void)bringOverlaysToFrontInWindow:(nullable UIWindow *)window;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* The overlay containers attached to the window, front to back.
|
|
35
|
+
*/
|
|
36
|
+
+ (NSArray<UIView *> *)overlayContainersInWindow:(nullable UIWindow *)window;
|
|
37
|
+
|
|
38
|
+
@end
|
|
39
|
+
|
|
40
|
+
NS_ASSUME_NONNULL_END
|
|
41
|
+
|
|
42
|
+
#endif
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Created by Jovanni Lo (@lodev09)
|
|
3
|
+
// Copyright (c) 2024-present. All rights reserved.
|
|
4
|
+
//
|
|
5
|
+
// This source code is licensed under the MIT license found in the
|
|
6
|
+
// LICENSE file in the root directory of this source tree.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
10
|
+
|
|
11
|
+
#import "TrueSheetOverlayView.h"
|
|
12
|
+
#import "core/TrueSheetOverlayContainerView.h"
|
|
13
|
+
|
|
14
|
+
#import <react/renderer/components/TrueSheetSpec/EventEmitters.h>
|
|
15
|
+
#import <react/renderer/components/TrueSheetSpec/Props.h>
|
|
16
|
+
#import <react/renderer/components/TrueSheetSpec/RCTComponentViewHelpers.h>
|
|
17
|
+
#import <react/renderer/components/TrueSheetSpec/TrueSheetOverlayViewComponentDescriptor.h>
|
|
18
|
+
#import <react/renderer/components/TrueSheetSpec/TrueSheetOverlayViewShadowNode.h>
|
|
19
|
+
|
|
20
|
+
#import <React/RCTSurfaceTouchHandler.h>
|
|
21
|
+
|
|
22
|
+
using namespace facebook::react;
|
|
23
|
+
|
|
24
|
+
NSNotificationName const TrueSheetOverlayWindowDidChangeNotification = @"TrueSheetOverlayWindowDidChangeNotification";
|
|
25
|
+
|
|
26
|
+
static NSHashTable<TrueSheetOverlayView *> *gOverlayViews;
|
|
27
|
+
|
|
28
|
+
@interface TrueSheetOverlayView () <TrueSheetOverlayContainerViewDelegate>
|
|
29
|
+
@end
|
|
30
|
+
|
|
31
|
+
@implementation TrueSheetOverlayView {
|
|
32
|
+
TrueSheetOverlayContainerView *_containerView;
|
|
33
|
+
// Owns `_containerView` so it has a view controller in its responder chain. The
|
|
34
|
+
// container is a sibling of `rootViewController.view`, and a window's responder chain
|
|
35
|
+
// skips its root view controller — without an owner, `-[UIView reactViewController]`
|
|
36
|
+
// finds nothing and content that installs a view controller cannot attach.
|
|
37
|
+
UIViewController *_containerController;
|
|
38
|
+
RCTSurfaceTouchHandler *_touchHandler;
|
|
39
|
+
TrueSheetOverlayViewShadowNode::ConcreteState::Shared _state;
|
|
40
|
+
CGSize _lastStateSize;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
+ (ComponentDescriptorProvider)componentDescriptorProvider {
|
|
44
|
+
return concreteComponentDescriptorProvider<TrueSheetOverlayViewComponentDescriptor>();
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
+ (void)bringOverlaysToFrontInWindow:(nullable UIWindow *)window {
|
|
48
|
+
if (!window)
|
|
49
|
+
return;
|
|
50
|
+
|
|
51
|
+
for (TrueSheetOverlayView *overlay in gOverlayViews) {
|
|
52
|
+
if (overlay->_containerView.superview == window) {
|
|
53
|
+
[window bringSubviewToFront:overlay->_containerView];
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
+ (NSArray<UIView *> *)overlayContainersInWindow:(nullable UIWindow *)window {
|
|
59
|
+
NSMutableArray<UIView *> *containers = [NSMutableArray array];
|
|
60
|
+
for (UIView *subview in window.subviews.reverseObjectEnumerator) {
|
|
61
|
+
if ([subview isKindOfClass:[TrueSheetOverlayContainerView class]]) {
|
|
62
|
+
[containers addObject:subview];
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return containers;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
- (instancetype)initWithFrame:(CGRect)frame {
|
|
69
|
+
if (self = [super initWithFrame:frame]) {
|
|
70
|
+
static const auto defaultProps = std::make_shared<const TrueSheetOverlayViewProps>();
|
|
71
|
+
_props = defaultProps;
|
|
72
|
+
|
|
73
|
+
_containerView = [[TrueSheetOverlayContainerView alloc] initWithFrame:CGRectZero];
|
|
74
|
+
_containerView.delegate = self;
|
|
75
|
+
|
|
76
|
+
// Assigning the container as its view is what puts the controller in the responder
|
|
77
|
+
// chain; the containment below is for lifecycle only.
|
|
78
|
+
_containerController = [UIViewController new];
|
|
79
|
+
_containerController.view = _containerView;
|
|
80
|
+
|
|
81
|
+
_touchHandler = [[RCTSurfaceTouchHandler alloc] init];
|
|
82
|
+
[_touchHandler attachToView:_containerView];
|
|
83
|
+
|
|
84
|
+
_lastStateSize = CGSizeZero;
|
|
85
|
+
|
|
86
|
+
// The host stays in the React tree for layout only — children render in the container
|
|
87
|
+
self.hidden = YES;
|
|
88
|
+
|
|
89
|
+
if (!gOverlayViews) {
|
|
90
|
+
gOverlayViews = [NSHashTable weakObjectsHashTable];
|
|
91
|
+
}
|
|
92
|
+
[gOverlayViews addObject:self];
|
|
93
|
+
}
|
|
94
|
+
return self;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
- (void)didMoveToWindow {
|
|
98
|
+
[super didMoveToWindow];
|
|
99
|
+
|
|
100
|
+
UIWindow *window = self.window;
|
|
101
|
+
if (window) {
|
|
102
|
+
_containerView.frame = window.bounds;
|
|
103
|
+
[window addSubview:_containerView];
|
|
104
|
+
|
|
105
|
+
UIViewController *root = window.rootViewController;
|
|
106
|
+
if (root != nil && _containerController.parentViewController != root) {
|
|
107
|
+
[root addChildViewController:_containerController];
|
|
108
|
+
[_containerController didMoveToParentViewController:root];
|
|
109
|
+
}
|
|
110
|
+
} else {
|
|
111
|
+
[_containerController willMoveToParentViewController:nil];
|
|
112
|
+
[_containerView removeFromSuperview];
|
|
113
|
+
[_containerController removeFromParentViewController];
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
[[NSNotificationCenter defaultCenter] postNotificationName:TrueSheetOverlayWindowDidChangeNotification object:nil];
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
#pragma mark - State
|
|
120
|
+
|
|
121
|
+
- (void)updateState:(const State::Shared &)state oldState:(const State::Shared &)oldState {
|
|
122
|
+
_state = std::static_pointer_cast<TrueSheetOverlayViewShadowNode::ConcreteState const>(state);
|
|
123
|
+
|
|
124
|
+
if (self.window) {
|
|
125
|
+
[self updateStateWithSize:self.window.bounds.size];
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
- (void)overlayContainerViewDidLayout:(CGSize)size {
|
|
130
|
+
[self updateStateWithSize:size];
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
- (void)updateStateWithSize:(CGSize)size {
|
|
134
|
+
if (!_state)
|
|
135
|
+
return;
|
|
136
|
+
|
|
137
|
+
if (fabs(size.width - _lastStateSize.width) < 0.5 && fabs(size.height - _lastStateSize.height) < 0.5)
|
|
138
|
+
return;
|
|
139
|
+
|
|
140
|
+
_lastStateSize = size;
|
|
141
|
+
|
|
142
|
+
auto stateData = _state->getData();
|
|
143
|
+
stateData.containerWidth = static_cast<float>(size.width);
|
|
144
|
+
stateData.containerHeight = static_cast<float>(size.height);
|
|
145
|
+
_state->updateState(std::move(stateData), EventQueue::UpdateMode::unstable_Immediate);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
#pragma mark - Child Component Mounting
|
|
149
|
+
|
|
150
|
+
- (void)mountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index {
|
|
151
|
+
[_containerView insertSubview:childComponentView atIndex:index];
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
- (void)unmountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index {
|
|
155
|
+
[childComponentView removeFromSuperview];
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
- (void)prepareForRecycle {
|
|
159
|
+
[super prepareForRecycle];
|
|
160
|
+
|
|
161
|
+
[_containerController willMoveToParentViewController:nil];
|
|
162
|
+
[_containerView removeFromSuperview];
|
|
163
|
+
[_containerController removeFromParentViewController];
|
|
164
|
+
_lastStateSize = CGSizeZero;
|
|
165
|
+
_state.reset();
|
|
166
|
+
self.hidden = YES;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
@end
|
|
170
|
+
|
|
171
|
+
Class<RCTComponentViewProtocol> TrueSheetOverlayViewCls(void) {
|
|
172
|
+
return TrueSheetOverlayView.class;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
#endif
|
package/ios/TrueSheetView.h
CHANGED
|
@@ -34,6 +34,8 @@ typedef void (^TrueSheetCompletionBlock)(BOOL success, NSError *_Nullable error)
|
|
|
34
34
|
|
|
35
35
|
- (void)emitDismissedPosition;
|
|
36
36
|
|
|
37
|
+
- (BOOL)cancelPendingPresent;
|
|
38
|
+
|
|
37
39
|
- (void)resizeToIndex:(NSInteger)index completion:(nullable TrueSheetCompletionBlock)completion;
|
|
38
40
|
|
|
39
41
|
- (void)dismissStackAnimated:(BOOL)animated completion:(nullable TrueSheetCompletionBlock)completion;
|