@lodev09/react-native-true-sheet 3.6.6 → 3.6.8
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.
|
@@ -2,6 +2,7 @@ package com.lodev09.truesheet
|
|
|
2
2
|
|
|
3
3
|
import android.annotation.SuppressLint
|
|
4
4
|
import android.view.View
|
|
5
|
+
import android.view.ViewGroup
|
|
5
6
|
import android.view.ViewStructure
|
|
6
7
|
import android.view.accessibility.AccessibilityEvent
|
|
7
8
|
import androidx.annotation.UiThread
|
|
@@ -64,6 +65,9 @@ class TrueSheetView(private val reactContext: ThemedReactContext) :
|
|
|
64
65
|
// Debounce flag to coalesce rapid layout changes into a single sheet update
|
|
65
66
|
private var isSheetUpdatePending: Boolean = false
|
|
66
67
|
|
|
68
|
+
// Root container for the coordinator layout (activity or Modal dialog content view)
|
|
69
|
+
private var rootContainerView: ViewGroup? = null
|
|
70
|
+
|
|
67
71
|
// ==================== Initialization ====================
|
|
68
72
|
|
|
69
73
|
init {
|
|
@@ -154,13 +158,16 @@ class TrueSheetView(private val reactContext: ThemedReactContext) :
|
|
|
154
158
|
|
|
155
159
|
fun onDropInstance() {
|
|
156
160
|
reactContext.removeLifecycleEventListener(this)
|
|
157
|
-
TrueSheetModule.unregisterView(id)
|
|
158
|
-
TrueSheetStackManager.removeSheet(this)
|
|
159
161
|
|
|
160
162
|
if (viewController.isPresented) {
|
|
161
163
|
viewController.dismiss(animated = false)
|
|
162
164
|
}
|
|
165
|
+
|
|
166
|
+
TrueSheetModule.unregisterView(id)
|
|
167
|
+
TrueSheetStackManager.removeSheet(this)
|
|
168
|
+
|
|
163
169
|
viewController.delegate = null
|
|
170
|
+
didInitiallyPresent = false
|
|
164
171
|
}
|
|
165
172
|
|
|
166
173
|
/**
|
|
@@ -262,6 +269,10 @@ class TrueSheetView(private val reactContext: ThemedReactContext) :
|
|
|
262
269
|
@UiThread
|
|
263
270
|
fun present(detentIndex: Int, animated: Boolean = true, promiseCallback: () -> Unit) {
|
|
264
271
|
if (!viewController.isPresented) {
|
|
272
|
+
// Attach coordinator to the root container
|
|
273
|
+
rootContainerView = findRootContainerView()
|
|
274
|
+
viewController.coordinatorLayout?.let { rootContainerView?.addView(it) }
|
|
275
|
+
|
|
265
276
|
// Register with observer to track sheet stack hierarchy
|
|
266
277
|
viewController.parentSheetView = TrueSheetStackManager.onSheetWillPresent(this, detentIndex)
|
|
267
278
|
}
|
|
@@ -387,6 +398,10 @@ class TrueSheetView(private val reactContext: ThemedReactContext) :
|
|
|
387
398
|
}
|
|
388
399
|
|
|
389
400
|
override fun viewControllerDidDismiss(hadParent: Boolean) {
|
|
401
|
+
// Detach coordinator from the root container view
|
|
402
|
+
viewController.coordinatorLayout?.let { rootContainerView?.removeView(it) }
|
|
403
|
+
rootContainerView = null
|
|
404
|
+
|
|
390
405
|
val surfaceId = UIManagerHelper.getSurfaceId(this)
|
|
391
406
|
eventDispatcher?.dispatchEvent(DidDismissEvent(surfaceId, id))
|
|
392
407
|
|
|
@@ -461,4 +476,25 @@ class TrueSheetView(private val reactContext: ThemedReactContext) :
|
|
|
461
476
|
// Footer changes don't affect detents, only reposition it
|
|
462
477
|
viewController.positionFooter()
|
|
463
478
|
}
|
|
479
|
+
|
|
480
|
+
// ==================== Private Helpers ====================
|
|
481
|
+
|
|
482
|
+
/**
|
|
483
|
+
* Find the root container view for presenting the sheet.
|
|
484
|
+
* This traverses up the view hierarchy to find the content view (android.R.id.content)
|
|
485
|
+
* of whichever window this view is in - whether that's the activity's window or a
|
|
486
|
+
* Modal's dialog window.
|
|
487
|
+
*/
|
|
488
|
+
private fun findRootContainerView(): ViewGroup? {
|
|
489
|
+
var current: android.view.ViewParent? = parent
|
|
490
|
+
|
|
491
|
+
while (current != null) {
|
|
492
|
+
if (current is ViewGroup && current.id == android.R.id.content) {
|
|
493
|
+
return current
|
|
494
|
+
}
|
|
495
|
+
current = current.parent
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
return reactContext.currentActivity?.findViewById(android.R.id.content)
|
|
499
|
+
}
|
|
464
500
|
}
|
|
@@ -110,7 +110,7 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
|
|
|
110
110
|
|
|
111
111
|
// CoordinatorLayout components (replaces DialogFragment)
|
|
112
112
|
internal var sheetView: TrueSheetBottomSheetView? = null
|
|
113
|
-
|
|
113
|
+
internal var coordinatorLayout: TrueSheetCoordinatorLayout? = null
|
|
114
114
|
private var dimView: TrueSheetDimView? = null
|
|
115
115
|
private var parentDimView: TrueSheetDimView? = null
|
|
116
116
|
|
|
@@ -303,9 +303,6 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
|
|
|
303
303
|
cleanupBackCallback()
|
|
304
304
|
sheetView?.animate()?.cancel()
|
|
305
305
|
|
|
306
|
-
// Remove from activity
|
|
307
|
-
removeFromActivity()
|
|
308
|
-
|
|
309
306
|
// Cleanup dim views
|
|
310
307
|
dimView?.detach()
|
|
311
308
|
dimView = null
|
|
@@ -330,12 +327,6 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
|
|
|
330
327
|
shouldAnimatePresent = true
|
|
331
328
|
}
|
|
332
329
|
|
|
333
|
-
private fun removeFromActivity() {
|
|
334
|
-
val coordinator = coordinatorLayout ?: return
|
|
335
|
-
val contentView = reactContext.currentActivity?.findViewById<ViewGroup>(android.R.id.content)
|
|
336
|
-
contentView?.removeView(coordinator)
|
|
337
|
-
}
|
|
338
|
-
|
|
339
330
|
// =============================================================================
|
|
340
331
|
// MARK: - Back Button Handling
|
|
341
332
|
// =============================================================================
|
|
@@ -603,15 +594,6 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
|
|
|
603
594
|
// Setup sheet in coordinator layout
|
|
604
595
|
setupSheetInCoordinator(coordinator, sheet)
|
|
605
596
|
|
|
606
|
-
// Add coordinator to activity
|
|
607
|
-
val activity = reactContext.currentActivity ?: run {
|
|
608
|
-
RNLog.w(reactContext, "TrueSheet: No activity available for presentation.")
|
|
609
|
-
return
|
|
610
|
-
}
|
|
611
|
-
|
|
612
|
-
val contentView = activity.findViewById<ViewGroup>(android.R.id.content)
|
|
613
|
-
contentView?.addView(coordinator)
|
|
614
|
-
|
|
615
597
|
emitWillPresentEvents()
|
|
616
598
|
|
|
617
599
|
setupSheetDetents()
|
|
@@ -22,6 +22,7 @@ using namespace facebook::react;
|
|
|
22
22
|
CGFloat _lastHeight;
|
|
23
23
|
BOOL _didInitialLayout;
|
|
24
24
|
NSLayoutConstraint *_bottomConstraint;
|
|
25
|
+
CGFloat _currentKeyboardOffset;
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
+ (ComponentDescriptorProvider)componentDescriptorProvider {
|
|
@@ -39,6 +40,7 @@ using namespace facebook::react;
|
|
|
39
40
|
_lastHeight = 0;
|
|
40
41
|
_didInitialLayout = NO;
|
|
41
42
|
_bottomConstraint = nil;
|
|
43
|
+
_currentKeyboardOffset = 0;
|
|
42
44
|
}
|
|
43
45
|
return self;
|
|
44
46
|
}
|
|
@@ -59,8 +61,9 @@ using namespace facebook::react;
|
|
|
59
61
|
[self.leadingAnchor constraintEqualToAnchor:parentView.leadingAnchor].active = YES;
|
|
60
62
|
[self.trailingAnchor constraintEqualToAnchor:parentView.trailingAnchor].active = YES;
|
|
61
63
|
|
|
62
|
-
// Store bottom constraint for keyboard adjustment
|
|
63
|
-
_bottomConstraint = [self.bottomAnchor constraintEqualToAnchor:parentView.bottomAnchor
|
|
64
|
+
// Store bottom constraint for keyboard adjustment, preserving current keyboard offset
|
|
65
|
+
_bottomConstraint = [self.bottomAnchor constraintEqualToAnchor:parentView.bottomAnchor
|
|
66
|
+
constant:-_currentKeyboardOffset];
|
|
64
67
|
_bottomConstraint.active = YES;
|
|
65
68
|
|
|
66
69
|
// Apply height constraint
|
|
@@ -109,6 +112,7 @@ using namespace facebook::react;
|
|
|
109
112
|
_lastHeight = 0;
|
|
110
113
|
_didInitialLayout = NO;
|
|
111
114
|
_bottomConstraint = nil;
|
|
115
|
+
_currentKeyboardOffset = 0;
|
|
112
116
|
}
|
|
113
117
|
|
|
114
118
|
#pragma mark - Keyboard Handling
|
|
@@ -163,6 +167,9 @@ using namespace facebook::react;
|
|
|
163
167
|
// Cap to ensure we don't go negative
|
|
164
168
|
CGFloat bottomOffset = MAX(0, keyboardHeight);
|
|
165
169
|
|
|
170
|
+
// Store the current keyboard offset so it persists through constraint recreation
|
|
171
|
+
_currentKeyboardOffset = bottomOffset;
|
|
172
|
+
|
|
166
173
|
[UIView animateWithDuration:duration
|
|
167
174
|
delay:0
|
|
168
175
|
options:curve | UIViewAnimationOptionBeginFromCurrentState
|
package/ios/TrueSheetView.mm
CHANGED
|
@@ -258,13 +258,14 @@ using namespace facebook::react;
|
|
|
258
258
|
- (void)prepareForRecycle {
|
|
259
259
|
[super prepareForRecycle];
|
|
260
260
|
|
|
261
|
-
_lastStateSize = CGSizeZero;
|
|
262
|
-
|
|
263
261
|
if (_controller && _controller.presentingViewController) {
|
|
264
262
|
[_controller dismissViewControllerAnimated:YES completion:nil];
|
|
265
263
|
}
|
|
266
264
|
|
|
267
265
|
[TrueSheetModule unregisterViewWithTag:@(self.tag)];
|
|
266
|
+
|
|
267
|
+
_lastStateSize = CGSizeZero;
|
|
268
|
+
_didInitiallyPresent = NO;
|
|
268
269
|
}
|
|
269
270
|
|
|
270
271
|
#pragma mark - Child Component Mounting
|
package/package.json
CHANGED