Skip to content

Commit 6872736

Browse files
authored
fix: automatically detect top border of KeyboardAwareScrollView (#1352)
## 📜 Description Automatically detect top border of `KeyboardAwareScrollView`. ## 💡 Motivation and Context Continue the epic with better discovery of component location on the screen and logical continuation of #1346 In this PR I started to detect relative position of `ScrollView`, so that I better understand if caret is not visible because it obscured by other elements (header etc.) It's still not perfectly implemented and there is still a "blind"/"dead" zone where text is already hidden but scroll doesn't happen. I'll fix it in following PRs but for now I just want to bring these changes to upcoming `1.21.0` release 🤞 We also can't use `measureInWindow` because it produces incorrect measurements, so we need to use our custom implementation that has been added in #1355 Significantly improves UI for behavior described in #1341 ## 📢 Changelog <!-- High level overview of important changes --> <!-- For example: fixed status bar manipulation; added new types declarations; --> <!-- If your changes don't affect one of platform/language below - then remove this platform/language --> ### JS - auto detect position of `KeyboardAwareScrollView` on the screen to better understand top border of the component relative to screen; ## 🤔 How Has This Been Tested? Tested manually on iPhone 17 Pro (iOS 26.2, simulator). ## 📸 Screenshots (if appropriate): https://github.com/user-attachments/assets/43fe233f-9c83-40c9-9642-a68e2d8e8e7c ## 📝 Checklist - [x] CI successfully passed - [x] I added new mocks and corresponding unit-tests if library API was changed
1 parent eb2dfbb commit 6872736

1 file changed

Lines changed: 15 additions & 3 deletions

File tree

  • src/components/KeyboardAwareScrollView

src/components/KeyboardAwareScrollView/index.tsx

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import Reanimated, {
1616
useSharedValue,
1717
} from "react-native-reanimated";
1818

19+
import { KeyboardControllerNative } from "../../bindings";
1920
import {
2021
useFocusedInputHandler,
2122
useReanimatedFocusedInput,
@@ -150,14 +151,25 @@ const KeyboardAwareScrollView = forwardRef<
150151
useSharedValue<FocusedInputSelectionChangedEvent | null>(null);
151152
const ghostViewSpace = useSharedValue(-1);
152153
const pendingSelectionForFocus = useSharedValue(false);
154+
const scrollViewPageY = useSharedValue(0);
153155

154156
const { height } = useWindowDimensions();
155157

156158
const onScrollViewLayout = useCallback(
157-
(e: LayoutChangeEvent) => {
158-
scrollViewTarget.value = findNodeHandle(scrollViewAnimatedRef.current);
159+
async (e: LayoutChangeEvent) => {
160+
const handle = findNodeHandle(scrollViewAnimatedRef.current);
161+
162+
scrollViewTarget.value = handle;
159163

160164
onLayout?.(e);
165+
166+
if (handle !== null) {
167+
const { y } = await KeyboardControllerNative.viewPositionInWindow(
168+
handle,
169+
);
170+
171+
scrollViewPageY.value = y;
172+
}
161173
},
162174
[onLayout],
163175
);
@@ -205,7 +217,7 @@ const KeyboardAwareScrollView = forwardRef<
205217
return interpolatedScrollTo;
206218
}
207219

208-
if (point < 0) {
220+
if (point < scrollViewPageY.value) {
209221
const positionOnScreen = visibleRect - bottomOffset;
210222
const topOfScreen = scrollPosition.value + point;
211223

0 commit comments

Comments
 (0)