@lodev09/react-native-true-sheet 4.0.0-beta.26 → 4.0.0-beta.28
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/src/main/java/com/lodev09/truesheet/TrueSheetFooterView.kt +19 -1
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetStateUpdater.kt +11 -3
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewController.kt +20 -0
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetOverlayRootView.kt +8 -1
- package/android/src/main/jni/TrueSheetStateUpdater.cpp +37 -6
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewShadowNode.cpp +12 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewShadowNode.h +2 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewState.h +8 -2
- package/ios/TrueSheetFooterView.mm +27 -12
- package/ios/TrueSheetViewController.mm +9 -6
- package/package.json +1 -1
|
@@ -32,10 +32,24 @@ class TrueSheetFooterView(reactContext: ThemedReactContext) : ReactViewGroup(rea
|
|
|
32
32
|
|
|
33
33
|
private var lastWidth = 0
|
|
34
34
|
private var lastHeight = 0
|
|
35
|
+
private var stateTranslationY = 0f
|
|
35
36
|
|
|
36
37
|
var bottomInset = 0
|
|
37
38
|
private set
|
|
38
39
|
|
|
40
|
+
/**
|
|
41
|
+
* positionFooter slides the footer off its Yoga position (above the
|
|
42
|
+
* keyboard, or riding the sheet). Mirror where it rests into the shadow
|
|
43
|
+
* node so measure() — and Pressability's press region — match where it's
|
|
44
|
+
* drawn. Called once the footer settles: every push is a commit.
|
|
45
|
+
*/
|
|
46
|
+
fun syncTranslationState() {
|
|
47
|
+
if (translationY == stateTranslationY) return
|
|
48
|
+
val sw = stateWrapper ?: return
|
|
49
|
+
stateTranslationY = translationY
|
|
50
|
+
TrueSheetStateUpdater.updateFooterTranslation(sw, translationY.pxToDp())
|
|
51
|
+
}
|
|
52
|
+
|
|
39
53
|
/**
|
|
40
54
|
* Height the footer occupies above the keyboard — its layout height minus
|
|
41
55
|
* the safe-area inset, which rides below the keyboard's top edge while the
|
|
@@ -55,14 +69,18 @@ class TrueSheetFooterView(reactContext: ThemedReactContext) : ReactViewGroup(rea
|
|
|
55
69
|
|
|
56
70
|
val sw = stateWrapper ?: return
|
|
57
71
|
val insetDp = bottomInset.toFloat().pxToDp()
|
|
72
|
+
// Carried along — this update replaces a still-queued translation update
|
|
73
|
+
stateTranslationY = translationY
|
|
74
|
+
val translateYDp = translationY.pxToDp()
|
|
58
75
|
|
|
59
76
|
// Synchronous update — the footer must be padded before detents are
|
|
60
77
|
// configured, otherwise the auto detent is set up an inset short
|
|
61
|
-
if (TrueSheetStateUpdater.updateFooterState(sw, insetDp)) return
|
|
78
|
+
if (TrueSheetStateUpdater.updateFooterState(sw, insetDp, translateYDp)) return
|
|
62
79
|
|
|
63
80
|
// Fallback: async state update
|
|
64
81
|
val newState = WritableNativeMap()
|
|
65
82
|
newState.putDouble("bottomInset", insetDp.toDouble())
|
|
83
|
+
newState.putDouble("translateY", translateYDp.toDouble())
|
|
66
84
|
sw.updateState(newState)
|
|
67
85
|
}
|
|
68
86
|
|
|
@@ -41,8 +41,13 @@ object TrueSheetStateUpdater {
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
/** Returns false when unavailable — caller should fall back to async updateState. */
|
|
44
|
-
fun updateFooterState(stateWrapper: StateWrapper, bottomInsetDp: Float): Boolean =
|
|
45
|
-
isAvailable && nativeUpdateFooterState(stateWrapper, bottomInsetDp)
|
|
44
|
+
fun updateFooterState(stateWrapper: StateWrapper, bottomInsetDp: Float, translateYDp: Float): Boolean =
|
|
45
|
+
isAvailable && nativeUpdateFooterState(stateWrapper, bottomInsetDp, translateYDp)
|
|
46
|
+
|
|
47
|
+
/** Mirrors the footer's native translation so measure() matches where it's drawn. */
|
|
48
|
+
fun updateFooterTranslation(stateWrapper: StateWrapper, translateYDp: Float) {
|
|
49
|
+
if (isAvailable) nativeUpdateFooterTranslation(stateWrapper, translateYDp)
|
|
50
|
+
}
|
|
46
51
|
|
|
47
52
|
/**
|
|
48
53
|
* Publishes the precalculated bottom safe-area inset so a late-mounted
|
|
@@ -56,7 +61,10 @@ object TrueSheetStateUpdater {
|
|
|
56
61
|
private external fun nativeUpdateState(stateWrapper: Any, width: Float, height: Float): Boolean
|
|
57
62
|
|
|
58
63
|
@JvmStatic
|
|
59
|
-
private external fun nativeUpdateFooterState(stateWrapper: Any, bottomInset: Float): Boolean
|
|
64
|
+
private external fun nativeUpdateFooterState(stateWrapper: Any, bottomInset: Float, translateY: Float): Boolean
|
|
65
|
+
|
|
66
|
+
@JvmStatic
|
|
67
|
+
private external fun nativeUpdateFooterTranslation(stateWrapper: Any, translateY: Float)
|
|
60
68
|
|
|
61
69
|
@JvmStatic
|
|
62
70
|
private external fun nativeSetBottomSafeArea(insetDp: Float)
|
|
@@ -374,6 +374,13 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
|
|
|
374
374
|
private val isKeyboardTransitioning: Boolean
|
|
375
375
|
get() = keyboardObserver?.isTransitioning ?: false
|
|
376
376
|
|
|
377
|
+
// The footer slides every frame until the sheet and keyboard come to rest
|
|
378
|
+
private val isSheetMoving: Boolean
|
|
379
|
+
get() = isPresentAnimating ||
|
|
380
|
+
isKeyboardTransitioning ||
|
|
381
|
+
behavior?.state == BottomSheetBehavior.STATE_DRAGGING ||
|
|
382
|
+
behavior?.state == BottomSheetBehavior.STATE_SETTLING
|
|
383
|
+
|
|
377
384
|
// Keyboard is up or animating — detents are (or are about to be) keyboard-shifted
|
|
378
385
|
val isKeyboardActive: Boolean
|
|
379
386
|
get() = keyboardInset > 0 || isKeyboardTransitioning
|
|
@@ -724,6 +731,9 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
|
|
|
724
731
|
}
|
|
725
732
|
|
|
726
733
|
private fun handleStateSettled(sheetView: View, newState: Int) {
|
|
734
|
+
// The settle's last slide frame has positioned the footer
|
|
735
|
+
containerView?.footerView?.syncTranslationState()
|
|
736
|
+
|
|
727
737
|
if (interactionState is InteractionState.Reconfiguring) return
|
|
728
738
|
|
|
729
739
|
// A release already at a stop settles without a slide frame
|
|
@@ -1288,6 +1298,7 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
|
|
|
1288
1298
|
// absolute footer floats above it
|
|
1289
1299
|
if (!absoluteFooter) {
|
|
1290
1300
|
footerView.translationY = 0f
|
|
1301
|
+
footerView.syncTranslationState()
|
|
1291
1302
|
return
|
|
1292
1303
|
}
|
|
1293
1304
|
|
|
@@ -1313,6 +1324,9 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
|
|
|
1313
1324
|
// Clamp to prevent footer going above safe area
|
|
1314
1325
|
val maxAllowedY = (sheetHeight - topInset - footerHeight).toFloat()
|
|
1315
1326
|
footerView.y = minOf(footerY, maxAllowedY)
|
|
1327
|
+
// Mid-motion slides are synced once the sheet settles or the keyboard
|
|
1328
|
+
// lands (handleStateSettled, keyboardDidShow/keyboardDidHide)
|
|
1329
|
+
if (!isSheetMoving) footerView.syncTranslationState()
|
|
1316
1330
|
if (!footerAvoidsKeyboard) {
|
|
1317
1331
|
containerView?.contentView?.updateContentInset()
|
|
1318
1332
|
}
|
|
@@ -1403,7 +1417,13 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
|
|
|
1403
1417
|
)
|
|
1404
1418
|
}
|
|
1405
1419
|
|
|
1420
|
+
override fun keyboardDidShow(height: Int) {
|
|
1421
|
+
// The keyboard's last frame has positioned the footer
|
|
1422
|
+
containerView?.footerView?.syncTranslationState()
|
|
1423
|
+
}
|
|
1424
|
+
|
|
1406
1425
|
override fun keyboardDidHide() {
|
|
1426
|
+
containerView?.footerView?.syncTranslationState()
|
|
1407
1427
|
if (!shouldHandleKeyboard(checkFocus = false)) return
|
|
1408
1428
|
isKeyboardDismissProgrammatic = false
|
|
1409
1429
|
// Keep detentIndexBeforeKeyboard for the settle's detent-change check
|
|
@@ -48,7 +48,14 @@ class TrueSheetOverlayRootView(private val reactContext: ThemedReactContext) :
|
|
|
48
48
|
translationZ = OVERLAY_Z
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
// Children are positioned by Fabric — a FrameLayout pass would stretch them to match_parent
|
|
51
|
+
// Children are measured and positioned by Fabric — a FrameLayout pass would stretch them to match_parent
|
|
52
|
+
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
|
|
53
|
+
setMeasuredDimension(
|
|
54
|
+
MeasureSpec.getSize(widthMeasureSpec),
|
|
55
|
+
MeasureSpec.getSize(heightMeasureSpec)
|
|
56
|
+
)
|
|
57
|
+
}
|
|
58
|
+
|
|
52
59
|
override fun onLayout(
|
|
53
60
|
changed: Boolean,
|
|
54
61
|
left: Int,
|
|
@@ -58,7 +58,8 @@ static jboolean updateStateImmediate(
|
|
|
58
58
|
static jboolean updateFooterStateImmediate(
|
|
59
59
|
jni::alias_ref<jclass> /*clazz*/,
|
|
60
60
|
jni::alias_ref<jobject> stateWrapper,
|
|
61
|
-
jfloat bottomInset
|
|
61
|
+
jfloat bottomInset,
|
|
62
|
+
jfloat translateY) {
|
|
62
63
|
auto state = getStateFromWrapper(stateWrapper);
|
|
63
64
|
if (!state) {
|
|
64
65
|
return JNI_FALSE;
|
|
@@ -67,15 +68,44 @@ static jboolean updateFooterStateImmediate(
|
|
|
67
68
|
auto concreteState =
|
|
68
69
|
std::static_pointer_cast<const ConcreteState<TrueSheetFooterViewState>>(state);
|
|
69
70
|
|
|
70
|
-
//
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
71
|
+
// Carries the translation too — RN's EventQueue drops a still-queued update
|
|
72
|
+
// for the same view (see updateFooterTranslation) when this one is enqueued
|
|
73
|
+
concreteState->updateState(
|
|
74
|
+
[bottomInset, translateY](const TrueSheetFooterViewState &oldData) -> StateData::Shared {
|
|
75
|
+
auto newData = oldData;
|
|
76
|
+
newData.bottomInset = bottomInset;
|
|
77
|
+
newData.translateY = translateY;
|
|
78
|
+
newData.initialized = true;
|
|
79
|
+
return std::make_shared<const TrueSheetFooterViewState>(newData);
|
|
80
|
+
},
|
|
81
|
+
EventQueue::UpdateMode::unstable_Immediate);
|
|
75
82
|
|
|
76
83
|
return JNI_TRUE;
|
|
77
84
|
}
|
|
78
85
|
|
|
86
|
+
// Mirrors the footer's resting translation into its state so measure()
|
|
87
|
+
// matches where it's drawn. Async — it only feeds measure().
|
|
88
|
+
static void updateFooterTranslation(
|
|
89
|
+
jni::alias_ref<jclass> /*clazz*/,
|
|
90
|
+
jni::alias_ref<jobject> stateWrapper,
|
|
91
|
+
jfloat translateY) {
|
|
92
|
+
auto state = getStateFromWrapper(stateWrapper);
|
|
93
|
+
if (!state) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
auto concreteState =
|
|
98
|
+
std::static_pointer_cast<const ConcreteState<TrueSheetFooterViewState>>(state);
|
|
99
|
+
|
|
100
|
+
concreteState->updateState(
|
|
101
|
+
[translateY](const TrueSheetFooterViewState &oldData) -> StateData::Shared {
|
|
102
|
+
auto newData = oldData;
|
|
103
|
+
newData.translateY = translateY;
|
|
104
|
+
return std::make_shared<const TrueSheetFooterViewState>(newData);
|
|
105
|
+
},
|
|
106
|
+
EventQueue::UpdateMode::Asynchronous);
|
|
107
|
+
}
|
|
108
|
+
|
|
79
109
|
// Publishes the precalculated bottom safe-area inset so a late-mounted
|
|
80
110
|
// footer's first layout is already padded (see TrueSheetFooterViewShadowNode).
|
|
81
111
|
static void setBottomSafeArea(jni::alias_ref<jclass> /*clazz*/, jfloat insetDp) {
|
|
@@ -90,6 +120,7 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void * /*reserved*/) {
|
|
|
90
120
|
->registerNatives({
|
|
91
121
|
makeNativeMethod("nativeUpdateState", facebook::react::updateStateImmediate),
|
|
92
122
|
makeNativeMethod("nativeUpdateFooterState", facebook::react::updateFooterStateImmediate),
|
|
123
|
+
makeNativeMethod("nativeUpdateFooterTranslation", facebook::react::updateFooterTranslation),
|
|
93
124
|
makeNativeMethod("nativeSetBottomSafeArea", facebook::react::setBottomSafeArea),
|
|
94
125
|
});
|
|
95
126
|
});
|
package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewShadowNode.cpp
CHANGED
|
@@ -59,4 +59,16 @@ void TrueSheetFooterViewShadowNode::adjustLayoutWithState() {
|
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
+
// Native moves the footer off its Yoga position without a layout pass. Folding
|
|
63
|
+
// that slide into the transform keeps measure() — and Pressability's press
|
|
64
|
+
// region — on the drawn footer.
|
|
65
|
+
Transform TrueSheetFooterViewShadowNode::getTransform() const {
|
|
66
|
+
auto transform = ConcreteViewShadowNode::getTransform();
|
|
67
|
+
auto translateY = getStateData().translateY;
|
|
68
|
+
if (translateY == 0) {
|
|
69
|
+
return transform;
|
|
70
|
+
}
|
|
71
|
+
return transform * Transform::Translate(0, translateY, 0);
|
|
72
|
+
}
|
|
73
|
+
|
|
62
74
|
} // namespace facebook::react
|
|
@@ -11,7 +11,8 @@ namespace facebook::react {
|
|
|
11
11
|
/*
|
|
12
12
|
* State for <TrueSheetFooterView> component.
|
|
13
13
|
* Set from native with the sheet's bottom safe-area inset so the shadow node
|
|
14
|
-
* pads the footer's bottom edge
|
|
14
|
+
* pads the footer's bottom edge, and with the footer's native translation so
|
|
15
|
+
* measure() matches where it's drawn (see TrueSheetFooterViewShadowNode).
|
|
15
16
|
*/
|
|
16
17
|
class TrueSheetFooterViewState final {
|
|
17
18
|
public:
|
|
@@ -19,11 +20,16 @@ class TrueSheetFooterViewState final {
|
|
|
19
20
|
|
|
20
21
|
#ifdef ANDROID
|
|
21
22
|
TrueSheetFooterViewState(TrueSheetFooterViewState const &previousState, folly::dynamic data)
|
|
22
|
-
: bottomInset(static_cast<float>(data["bottomInset"].getDouble())),
|
|
23
|
+
: bottomInset(static_cast<float>(data["bottomInset"].getDouble())),
|
|
24
|
+
translateY(static_cast<float>(data["translateY"].getDouble())),
|
|
25
|
+
initialized(true) {
|
|
23
26
|
}
|
|
24
27
|
#endif
|
|
25
28
|
|
|
26
29
|
float bottomInset{0};
|
|
30
|
+
// Native slide off the Yoga position — above the keyboard, or riding the
|
|
31
|
+
// sheet below its lowest detent (Android)
|
|
32
|
+
float translateY{0};
|
|
27
33
|
// True once native has pushed a real inset — until then the shadow node
|
|
28
34
|
// seeds the layout from TrueSheetInsets (see TrueSheetFooterViewShadowNode)
|
|
29
35
|
bool initialized{false};
|
|
@@ -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
|
|
|
@@ -215,7 +229,7 @@ using namespace facebook::react;
|
|
|
215
229
|
[self setKeyboardVisible:YES];
|
|
216
230
|
|
|
217
231
|
CGFloat slide = [self keyboardSlideForHeight:height];
|
|
218
|
-
|
|
232
|
+
[self setKeyboardOffset:slide];
|
|
219
233
|
|
|
220
234
|
[UIView animateWithDuration:duration
|
|
221
235
|
delay:0
|
|
@@ -230,8 +244,9 @@ using namespace facebook::react;
|
|
|
230
244
|
}
|
|
231
245
|
|
|
232
246
|
- (void)keyboardWillHide:(NSTimeInterval)duration curve:(UIViewAnimationOptions)curve {
|
|
247
|
+
// Offset first — the visible push replaces it in the queue, one commit
|
|
248
|
+
[self setKeyboardOffset:0];
|
|
233
249
|
[self setKeyboardVisible:NO];
|
|
234
|
-
_currentKeyboardOffset = 0;
|
|
235
250
|
|
|
236
251
|
[UIView animateWithDuration:duration
|
|
237
252
|
delay:0
|
|
@@ -266,8 +281,8 @@ using namespace facebook::react;
|
|
|
266
281
|
|
|
267
282
|
// avoidKeyboard flipped off mid-keyboard — drop the slide already applied
|
|
268
283
|
if (![self floatsAboveKeyboard]) {
|
|
284
|
+
[self setKeyboardOffset:0];
|
|
269
285
|
[self setKeyboardVisible:NO];
|
|
270
|
-
_currentKeyboardOffset = 0;
|
|
271
286
|
self.transform = CGAffineTransformIdentity;
|
|
272
287
|
return;
|
|
273
288
|
}
|
|
@@ -275,7 +290,7 @@ using namespace facebook::react;
|
|
|
275
290
|
[self setKeyboardVisible:YES];
|
|
276
291
|
|
|
277
292
|
CGFloat slide = [self keyboardSlideForHeight:height];
|
|
278
|
-
|
|
293
|
+
[self setKeyboardOffset:slide];
|
|
279
294
|
self.transform = CGAffineTransformMakeTranslation(0, -slide);
|
|
280
295
|
}
|
|
281
296
|
|
|
@@ -77,6 +77,9 @@ static char TrueSheetAccessibilityWindowPreviousElementsKey;
|
|
|
77
77
|
@implementation TrueSheetViewController {
|
|
78
78
|
TrueSheetPositionState _lastEmittedPositionState;
|
|
79
79
|
CGSize _lastReportedSize;
|
|
80
|
+
// Net of the footer's baked-in inset, snapshotted together: the inset updates
|
|
81
|
+
// with the footer's layout, but a size change mid-present is deferred to
|
|
82
|
+
// didPresent, so subtracting it live pairs a new inset with a stale height.
|
|
80
83
|
CGFloat _autoDetentHeight;
|
|
81
84
|
CGFloat _peekDetentHeight;
|
|
82
85
|
NSInteger _pendingDetentIndex;
|
|
@@ -1576,8 +1579,8 @@ static BOOL TrueSheetIsPhoneIdiom(void) {
|
|
|
1576
1579
|
*/
|
|
1577
1580
|
- (void)setupSheetDetentsForSizeChange {
|
|
1578
1581
|
if (@available(iOS 16.0, *)) {
|
|
1579
|
-
CGFloat autoHeight = [_detentCalculator autoHeightForKeyboardHeight:_keyboardHeight];
|
|
1580
|
-
CGFloat peekHeight = [_detentCalculator peekHeight];
|
|
1582
|
+
CGFloat autoHeight = [_detentCalculator autoHeightForKeyboardHeight:_keyboardHeight] - [self autoDetentBottomInset];
|
|
1583
|
+
CGFloat peekHeight = [_detentCalculator peekHeight] - [self peekDetentBottomInset];
|
|
1581
1584
|
|
|
1582
1585
|
if (fabs(autoHeight - _autoDetentHeight) < 0.5 && fabs(peekHeight - _peekDetentHeight) < 0.5) {
|
|
1583
1586
|
return;
|
|
@@ -1617,8 +1620,8 @@ static BOOL TrueSheetIsPhoneIdiom(void) {
|
|
|
1617
1620
|
[_detentCalculator clearResolvedHeights];
|
|
1618
1621
|
_hingeCorrections = 0;
|
|
1619
1622
|
|
|
1620
|
-
_autoDetentHeight = [_detentCalculator autoHeightForKeyboardHeight:_keyboardHeight];
|
|
1621
|
-
_peekDetentHeight = [_detentCalculator peekHeight];
|
|
1623
|
+
_autoDetentHeight = [_detentCalculator autoHeightForKeyboardHeight:_keyboardHeight] - [self autoDetentBottomInset];
|
|
1624
|
+
_peekDetentHeight = [_detentCalculator peekHeight] - [self peekDetentBottomInset];
|
|
1622
1625
|
|
|
1623
1626
|
for (NSInteger index = 0; index < self.detents.count; index++) {
|
|
1624
1627
|
id detent = self.detents[index];
|
|
@@ -1681,7 +1684,7 @@ static BOOL TrueSheetIsPhoneIdiom(void) {
|
|
|
1681
1684
|
return [self customDetentWithIdentifier:@"custom-auto"
|
|
1682
1685
|
atIndex:index
|
|
1683
1686
|
heightBlock:^CGFloat {
|
|
1684
|
-
return self->_autoDetentHeight
|
|
1687
|
+
return self->_autoDetentHeight;
|
|
1685
1688
|
}];
|
|
1686
1689
|
} else {
|
|
1687
1690
|
return [UISheetPresentationControllerDetent mediumDetent];
|
|
@@ -1693,7 +1696,7 @@ static BOOL TrueSheetIsPhoneIdiom(void) {
|
|
|
1693
1696
|
return [self customDetentWithIdentifier:@"custom-peek"
|
|
1694
1697
|
atIndex:index
|
|
1695
1698
|
heightBlock:^CGFloat {
|
|
1696
|
-
return self->_peekDetentHeight
|
|
1699
|
+
return self->_peekDetentHeight;
|
|
1697
1700
|
}];
|
|
1698
1701
|
} else {
|
|
1699
1702
|
return [UISheetPresentationControllerDetent mediumDetent];
|
package/package.json
CHANGED