Mobile Development 7 min read

How to Handle Soft Keyboard Overlap in iOS, Android, and React Native

This article examines the differing behaviors of soft keyboards on iOS and Android in both H5 and React Native environments, identifies the challenges they cause for popup and textarea components, and presents cross‑platform solutions using KeyboardAvoidingView, resize listeners, and RN keyboard events to ensure input fields remain visible.

Kuaishou E-commerce Frontend Team
Kuaishou E-commerce Frontend Team
Kuaishou E-commerce Frontend Team
How to Handle Soft Keyboard Overlap in iOS, Android, and React Native

Problem

A multi‑platform (RN) project needs a comment feature where a popup contains a

<Textarea>

. When the soft keyboard appears, it often covers the input field, causing various layout issues.

Key Questions

Why do iOS and Android keyboards behave differently?

How do H5 and React Native keyboards differ?

What happens when the keyboard hides?

What compatibility solutions exist?

When Input Focuses/Blurs

iOS (H5) Keyboard

Show behavior

On iOS, focusing an input or textarea triggers the keyboard, but the WebView height does not change; instead the whole page scrolls upward, with the maximum scroll offset equal to the keyboard height.

Hide behavior

Pressing the keyboard’s hide button or tapping outside the input causes the input to lose focus and the keyboard to retract.

Android (H5) Keyboard

Show behavior

On Android, focusing an input brings up the keyboard and the WebView height shrinks by the keyboard height, leaving the remaining visible area for content; the WebView itself cannot scroll.

Hide behavior

Tapping outside the input removes focus and hides the keyboard. Tapping the keyboard’s hide button hides the keyboard without removing focus.

React Native Keyboard

Show behavior

The page does not resize; the keyboard simply overlays the view.

Hide behavior

The page remains unchanged when the keyboard hides.

Solutions

For iOS (H5), listen to the input focus event. When the keyboard appears, scroll the page to the top after a short delay (≈200 ms) so the popup stays visible. When the keyboard hides, restore the original state.

<code>const isIOS =
  Platform.OS === 'web'
    ? !!window.navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/)
    : Platform.OS === 'ios';
const onFocusIOSH5 = useCallback(() => {
  if (isIOS && isH5) {
    setIsKeyboardShow(true);
    const height = Math.max(docClientHeight(), bodyClientHeight());
    timeRef.current = window.setTimeout(() => {
      setContainerHeight(afterFocusHeight);
      window.scrollTo(0, height);
      clearTimeout(timeRef.current);
    }, 200);
  }
}, []);
const onBlurIOSH5 = useCallback(() => {
  if (isIOS && isH5) {
    setContainerHeight(0);
    setIsKeyboardShow(false);
  }
}, []);
</code>

For Android (H5), because focus events cannot reliably detect keyboard appearance, listen to the window resize event and handle the layout accordingly.

<code>useEffect(() => {
  if (isH5 && isAndroid) {
    window.addEventListener('resize', androidKeyboardHandler);
    return () => {
      window.removeEventListener('resize', androidKeyboardHandler);
    };
  }
}, []);
</code>

For iOS (RN) and Android (RN), use React Native’s Keyboard events. Android listens to keyboardDidShow / keyboardDidHide , while iOS listens to keyboardWillShow / keyboardWillHide . Adjust the container’s bottom margin based on the keyboard height.

<code>useEffect(() => {
  if (!isAndroid) {
    keyboardShowEvent.current = Keyboard.addListener('keyboardWillShow', (e) => {
      setIsKeyboardShow(true);
      if (!isIOS) return;
      const keyboardHeight = e?.endCoordinates?.height || 0;
      keyboardHeight && setContainerHeight(keyboardHeight + afterFocusHeight);
    });
    keyboardHideEvent.current = Keyboard.addListener('keyboardWillHide', () => {
      setIsKeyboardShow(false);
      setContainerHeight(0);
    });
  } else {
    keyboardShowEvent.current = Keyboard.addListener('keyboardDidShow', (e) => {
      setIsKeyboardShow(true);
      const keyboardHeight = e?.endCoordinates?.height || 0;
      keyboardHeight && setContainerHeight(keyboardHeight + afterFocusHeight + 20);
    });
    keyboardHideEvent.current = Keyboard.addListener('keyboardDidHide', () => {
      setIsKeyboardShow(false);
      setContainerHeight(0);
    });
  }
  return () => {
    keyboardShowEvent?.current?.remove();
    keyboardHideEvent?.current?.remove();
  };
}, [androidKeyboardHandler]);
</code>

These cross‑platform implementations successfully manage keyboard show/hide events. For edge cases—such as obscure device models or third‑party keyboards—additional UI strategies like auxiliary popups, larger bottom panels for long text, or modal dialogs can be employed to keep inputs visible.

iOSAndroidmobile UIReact Nativesoft keyboardkeyboard handling
Kuaishou E-commerce Frontend Team
Written by

Kuaishou E-commerce Frontend Team

Kuaishou E-commerce Frontend Team, welcome to join us

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.