From 2abce1981d26b786e74eeebb8eed7251436496ac Mon Sep 17 00:00:00 2001 From: anshulsingh1210 Date: Wed, 24 Jun 2026 20:33:59 +0530 Subject: [PATCH] fix: jitter removed in keyboard avoiding view behaviour --- src/components/KeyboardAvoidingView/index.tsx | 25 +++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/src/components/KeyboardAvoidingView/index.tsx b/src/components/KeyboardAvoidingView/index.tsx index ec2ee2961c..ba103ca304 100644 --- a/src/components/KeyboardAvoidingView/index.tsx +++ b/src/components/KeyboardAvoidingView/index.tsx @@ -120,11 +120,26 @@ const KeyboardAvoidingView = forwardRef< (layout: LayoutRectangle) => { "worklet"; - if ( - keyboard.isClosed.value || - initialFrame.value === null || - behavior !== "height" - ) { + // Reject out-of-order `automaticOffset` measurements to stop the onLayout flicker. + // + // With `automaticOffset`, every onLayout resolves the frame through an async + // native `viewPositionInWindow()` call. Those promises settle out of order, so + // a callback can arrive LATE carrying a stale, smaller `y`/`height` after a + // newer, larger one already landed. Since `initialFrame` is re-recorded on + // every onLayout and feeds `relativeKeyboardHeight()` (which drives the + // padding/offset), each stale value yanks the frame back down and produces the + // up-down jitter we saw while the keyboard opens. + // + // The view's bottom edge (`y + height`) only grows as the keyboard opens, so we + // accept a layout only when its bottom edge exceeds the stored one — this drops + // the late/stale callbacks and lets the frame ramp up monotonically and settle. + // The genuine resting frame is re-captured on the next `keyboard.isClosed` pass + // (or the first layout), so it never stays stuck at an inflated value across + // open/close cycles. + if (keyboard.isClosed.value || initialFrame.value === null) { + // eslint-disable-next-line react-compiler/react-compiler + initialFrame.value = layout; + } else if (behavior !== "height" && layout.y+layout.height > initialFrame.value.y+initialFrame.value.height) { // eslint-disable-next-line react-compiler/react-compiler initialFrame.value = layout; }