@swmansion/react-native-bottom-sheet 0.15.0-next.6 → 0.15.0-next.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.
|
@@ -825,12 +825,42 @@ class BottomSheetHostView(context: Context) : ReactViewGroup(context) {
|
|
|
825
825
|
}
|
|
826
826
|
}
|
|
827
827
|
|
|
828
|
-
if (
|
|
828
|
+
if (isVerticallyScrollable(view)) {
|
|
829
829
|
return view
|
|
830
830
|
}
|
|
831
831
|
return null
|
|
832
832
|
}
|
|
833
833
|
|
|
834
|
+
private fun isVerticallyScrollable(view: View): Boolean {
|
|
835
|
+
if (!view.canScrollVertically(1) && !view.canScrollVertically(-1)) {
|
|
836
|
+
return false
|
|
837
|
+
}
|
|
838
|
+
return getReactScrollEnabled(view) != false
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
private fun getReactScrollEnabled(view: View): Boolean? {
|
|
842
|
+
val method =
|
|
843
|
+
try {
|
|
844
|
+
view.javaClass.getMethod("getScrollEnabled")
|
|
845
|
+
} catch (_: NoSuchMethodException) {
|
|
846
|
+
return null
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
if (
|
|
850
|
+
method.returnType != Boolean::class.javaPrimitiveType &&
|
|
851
|
+
method.returnType != Boolean::class.javaObjectType
|
|
852
|
+
) {
|
|
853
|
+
return null
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
return try {
|
|
857
|
+
method.isAccessible = true
|
|
858
|
+
method.invoke(view) as? Boolean
|
|
859
|
+
} catch (_: Exception) {
|
|
860
|
+
null
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
|
|
834
864
|
private fun isViewInverted(view: View): Boolean {
|
|
835
865
|
val values = FloatArray(9)
|
|
836
866
|
var current: View? = view
|
|
@@ -189,10 +189,18 @@ public final class BottomSheetHostingView: UIView {
|
|
|
189
189
|
}
|
|
190
190
|
|
|
191
191
|
private var presentedSheetFrame: CGRect {
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
192
|
+
guard activeSpring != nil else { return sheetContainer.frame }
|
|
193
|
+
// Mid-settle, derive the on-screen frame from the spring instead of the
|
|
194
|
+
// presentation layer (which lags one commit behind right after a snap
|
|
195
|
+
// starts). The container's transform is translation-only.
|
|
196
|
+
let size = sheetContainer.bounds.size
|
|
197
|
+
let center = sheetContainer.center
|
|
198
|
+
return CGRect(
|
|
199
|
+
x: center.x - size.width / 2,
|
|
200
|
+
y: center.y - size.height / 2 + currentTranslationY,
|
|
201
|
+
width: size.width,
|
|
202
|
+
height: size.height
|
|
203
|
+
)
|
|
196
204
|
}
|
|
197
205
|
|
|
198
206
|
override public func point(inside point: CGPoint, with _: UIEvent?) -> Bool {
|
|
@@ -518,7 +526,7 @@ public final class BottomSheetHostingView: UIView {
|
|
|
518
526
|
|
|
519
527
|
@discardableResult
|
|
520
528
|
private func cancelActiveSpring() -> CGFloat {
|
|
521
|
-
let visualTy =
|
|
529
|
+
let visualTy = currentTranslationY
|
|
522
530
|
activeSpring = nil
|
|
523
531
|
activeSpringEmitsSettle = false
|
|
524
532
|
stopDisplayLink()
|
|
@@ -612,6 +620,7 @@ public final class BottomSheetHostingView: UIView {
|
|
|
612
620
|
}
|
|
613
621
|
|
|
614
622
|
private func isVerticallyScrollable(_ scrollView: UIScrollView) -> Bool {
|
|
623
|
+
guard scrollView.isScrollEnabled else { return false }
|
|
615
624
|
let verticalInset = scrollView.adjustedContentInset.top + scrollView.adjustedContentInset.bottom
|
|
616
625
|
let visibleHeight = max(0, scrollView.bounds.height - verticalInset)
|
|
617
626
|
return scrollView.alwaysBounceVertical || scrollView.contentSize.height > visibleHeight
|
|
@@ -914,11 +923,15 @@ extension BottomSheetHostingView: UIGestureRecognizerDelegate {
|
|
|
914
923
|
private extension BottomSheetHostingView {
|
|
915
924
|
var currentTranslationY: CGFloat {
|
|
916
925
|
// During a settle the modal is driven by a keyframe animation on the render
|
|
917
|
-
// server
|
|
918
|
-
//
|
|
919
|
-
//
|
|
920
|
-
|
|
921
|
-
|
|
926
|
+
// server (the model `transform` already holds the final target), so read the
|
|
927
|
+
// analytical spring the keyframes were sampled from. The presentation layer
|
|
928
|
+
// is deliberately not used: right after a snap starts it still holds the
|
|
929
|
+
// previously committed transform, and that stale value (e.g. the identity
|
|
930
|
+
// transform from before the first layout) reads as a wide-open sheet — which
|
|
931
|
+
// briefly flashed the scrim on mount. A drag assigns `transform` directly,
|
|
932
|
+
// so outside a settle the model value is correct.
|
|
933
|
+
if let spring = activeSpring {
|
|
934
|
+
return spring.value(at: CACurrentMediaTime())
|
|
922
935
|
}
|
|
923
936
|
return sheetContainer.transform.ty
|
|
924
937
|
}
|
|
@@ -940,6 +953,14 @@ private extension BottomSheetHostingView {
|
|
|
940
953
|
return
|
|
941
954
|
}
|
|
942
955
|
|
|
956
|
+
// Until the first layout places the sheet, the identity transform reads as
|
|
957
|
+
// a fully-open sheet; keep the scrim hidden until the sheet is positioned.
|
|
958
|
+
if !hasLaidOut {
|
|
959
|
+
scrimView.alpha = 0
|
|
960
|
+
scrimView.isHidden = true
|
|
961
|
+
return
|
|
962
|
+
}
|
|
963
|
+
|
|
943
964
|
// If we're settled on the closed detent, dynamic detent/content updates can
|
|
944
965
|
// momentarily report a stale non-zero position. Keep scrim fully hidden.
|
|
945
966
|
if
|
package/package.json
CHANGED