Skip to content

Commit e2d7310

Browse files
authored
fix: react on enabled property toggle when keyboard open (KeyboardAwareScrollView) (#417)
## 📜 Description React on `enabled` property toggle when keyboard open in `KeyboardAwareScrollView` component. ## 💡 Motivation and Context Initially me and @IvanIhnatsiuk were thinking that in #350 it will be better to not handle keyboard appearance if `enabled=false`. But it turns out that it will produce issues like #414 So in this PR I'm always keeping a handler in `useKeyboardHandler` hook and instead I don't render additional padding if view is disabled (we are not making any scrolling because we already handle `enabled` property value in `maybeScroll`). Fixes #414 ## 📢 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 - don't put keyboard handlers conditionally; - make padding conditional depends on `enabled` property; ## 🤔 How Has This Been Tested? Tested manually on iPhone 15 Pro (iOS 17.4, simulator). ## 📸 Screenshots (if appropriate): <!-- Add screenshots/video if needed --> <!-- That would be highly appreciated if you can add how it looked before and after your changes --> |Before|After| |-------|-----| |![image](https://github.com/kirillzyusko/react-native-keyboard-controller/assets/22820318/e37f7dbc-b915-4f6c-993d-7b672672be66)|![image](https://github.com/kirillzyusko/react-native-keyboard-controller/assets/22820318/44127abe-4353-4aff-abf3-aa69491e5383)| |<video src="https://github.com/kirillzyusko/react-native-keyboard-controller/assets/22820318/54de59f6-4f5e-45cd-ae4b-aa34cea6f56c">|<video src="https://github.com/kirillzyusko/react-native-keyboard-controller/assets/22820318/4e4fccf0-9c1e-4a94-a12e-17a8412b2244">| ## 📝 Checklist - [x] CI successfully passed - [x] I added new mocks and corresponding unit-tests if library API was changed
1 parent 9a82fde commit e2d7310

File tree

1 file changed

+80
-80
lines changed
  • src/components/KeyboardAwareScrollView

1 file changed

+80
-80
lines changed

src/components/KeyboardAwareScrollView/index.tsx

Lines changed: 80 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -212,77 +212,74 @@ const KeyboardAwareScrollView = forwardRef<
212212
);
213213

214214
useSmoothKeyboardHandler(
215-
enabled
216-
? {
217-
onStart: (e) => {
218-
"worklet";
219-
220-
const keyboardWillChangeSize =
221-
keyboardHeight.value !== e.height && e.height > 0;
222-
keyboardWillAppear.value =
223-
e.height > 0 && keyboardHeight.value === 0;
224-
const keyboardWillHide = e.height === 0;
225-
const focusWasChanged =
226-
(tag.value !== e.target && e.target !== -1) ||
227-
keyboardWillChangeSize;
228-
229-
if (keyboardWillChangeSize) {
230-
initialKeyboardSize.value = keyboardHeight.value;
231-
}
232-
233-
if (keyboardWillHide) {
234-
// on back transition need to interpolate as [0, keyboardHeight]
235-
initialKeyboardSize.value = 0;
236-
scrollPosition.value = scrollBeforeKeyboardMovement.value;
237-
}
238-
239-
if (
240-
keyboardWillAppear.value ||
241-
keyboardWillChangeSize ||
242-
focusWasChanged
243-
) {
244-
// persist scroll value
245-
scrollPosition.value = position.value;
246-
// just persist height - later will be used in interpolation
247-
keyboardHeight.value = e.height;
248-
}
249-
250-
// focus was changed
251-
if (focusWasChanged) {
252-
tag.value = e.target;
253-
254-
// save position of focused text input when keyboard starts to move
255-
layout.value = input.value;
256-
// save current scroll position - when keyboard will hide we'll reuse
257-
// this value to achieve smooth hide effect
258-
scrollBeforeKeyboardMovement.value = position.value;
259-
}
260-
261-
if (focusWasChanged && !keyboardWillAppear.value) {
262-
// update position on scroll value, so `onEnd` handler
263-
// will pick up correct values
264-
position.value += maybeScroll(e.height, true);
265-
}
266-
},
267-
onMove: (e) => {
268-
"worklet";
269-
270-
currentKeyboardFrameHeight.value = e.height;
271-
272-
// if the user has set disableScrollOnKeyboardHide, only auto-scroll when the keyboard opens
273-
if (!disableScrollOnKeyboardHide || keyboardWillAppear.value) {
274-
maybeScroll(e.height);
275-
}
276-
},
277-
onEnd: (e) => {
278-
"worklet";
279-
280-
keyboardHeight.value = e.height;
281-
scrollPosition.value = position.value;
282-
},
215+
{
216+
onStart: (e) => {
217+
"worklet";
218+
219+
const keyboardWillChangeSize =
220+
keyboardHeight.value !== e.height && e.height > 0;
221+
keyboardWillAppear.value = e.height > 0 && keyboardHeight.value === 0;
222+
const keyboardWillHide = e.height === 0;
223+
const focusWasChanged =
224+
(tag.value !== e.target && e.target !== -1) ||
225+
keyboardWillChangeSize;
226+
227+
if (keyboardWillChangeSize) {
228+
initialKeyboardSize.value = keyboardHeight.value;
229+
}
230+
231+
if (keyboardWillHide) {
232+
// on back transition need to interpolate as [0, keyboardHeight]
233+
initialKeyboardSize.value = 0;
234+
scrollPosition.value = scrollBeforeKeyboardMovement.value;
235+
}
236+
237+
if (
238+
keyboardWillAppear.value ||
239+
keyboardWillChangeSize ||
240+
focusWasChanged
241+
) {
242+
// persist scroll value
243+
scrollPosition.value = position.value;
244+
// just persist height - later will be used in interpolation
245+
keyboardHeight.value = e.height;
246+
}
247+
248+
// focus was changed
249+
if (focusWasChanged) {
250+
tag.value = e.target;
251+
252+
// save position of focused text input when keyboard starts to move
253+
layout.value = input.value;
254+
// save current scroll position - when keyboard will hide we'll reuse
255+
// this value to achieve smooth hide effect
256+
scrollBeforeKeyboardMovement.value = position.value;
283257
}
284-
: {},
285-
[height, maybeScroll, disableScrollOnKeyboardHide, enabled],
258+
259+
if (focusWasChanged && !keyboardWillAppear.value) {
260+
// update position on scroll value, so `onEnd` handler
261+
// will pick up correct values
262+
position.value += maybeScroll(e.height, true);
263+
}
264+
},
265+
onMove: (e) => {
266+
"worklet";
267+
268+
currentKeyboardFrameHeight.value = e.height;
269+
270+
// if the user has set disableScrollOnKeyboardHide, only auto-scroll when the keyboard opens
271+
if (!disableScrollOnKeyboardHide || keyboardWillAppear.value) {
272+
maybeScroll(e.height);
273+
}
274+
},
275+
onEnd: (e) => {
276+
"worklet";
277+
278+
keyboardHeight.value = e.height;
279+
scrollPosition.value = position.value;
280+
},
281+
},
282+
[height, maybeScroll, disableScrollOnKeyboardHide],
286283
);
287284

288285
useAnimatedReaction(
@@ -303,16 +300,19 @@ const KeyboardAwareScrollView = forwardRef<
303300
);
304301

305302
const view = useAnimatedStyle(
306-
() => ({
307-
// animations become laggy when scrolling to the end of the `ScrollView` (when the last input is focused)
308-
// this happens because the layout recalculates on every frame. To avoid this we slightly increase padding
309-
// by `+1`. In this way we assure, that `scrollTo` will never scroll to the end, because it uses interpolation
310-
// from 0 to `keyboardHeight`, and here our padding is `keyboardHeight + 1`. It allows us not to re-run layout
311-
// re-calculation on every animation frame and it helps to achieve smooth animation.
312-
// see: https://github.com/kirillzyusko/react-native-keyboard-controller/pull/342
313-
paddingBottom: currentKeyboardFrameHeight.value + 1,
314-
}),
315-
[],
303+
() =>
304+
enabled
305+
? {
306+
// animations become laggy when scrolling to the end of the `ScrollView` (when the last input is focused)
307+
// this happens because the layout recalculates on every frame. To avoid this we slightly increase padding
308+
// by `+1`. In this way we assure, that `scrollTo` will never scroll to the end, because it uses interpolation
309+
// from 0 to `keyboardHeight`, and here our padding is `keyboardHeight + 1`. It allows us not to re-run layout
310+
// re-calculation on every animation frame and it helps to achieve smooth animation.
311+
// see: https://github.com/kirillzyusko/react-native-keyboard-controller/pull/342
312+
paddingBottom: currentKeyboardFrameHeight.value + 1,
313+
}
314+
: {},
315+
[enabled],
316316
);
317317

318318
return (

0 commit comments

Comments
 (0)