← Back to the library
MobileApplied · 7 min

The keyboard hides the input or the submit button

“On some screens the focused field or the Continue button ends up behind the keyboard. It started on Android after we bumped targetSdk or the Expo SDK, and on iOS it's off by exactly the header height.”

THE PRINCIPLE

Exactly one layer should react to the keyboard. When the OS, a KeyboardAvoidingView and a scroll view all adjust, inputs jump twice or not at all.

FIRST MOVES

  1. Check the Android baseline first: targetSdk 35+ on Android 15+ is edge-to-edge (Expo SDK 54 projects are edge-to-edge by default), so adjustResize no longer shrinks your layout. A KeyboardAvoidingView without a behavior then does nothing.
  2. If you use KeyboardAvoidingView, set behavior explicitly on both platforms (padding usually works best on iOS) and pass the header height (useHeaderHeight) as keyboardVerticalOffset when it sits under a navigation header.
  3. Don't combine Android softwareKeyboardLayoutMode "pan" with behavior="padding": the window and the view both move and the input shifts twice.
  4. For forms, chat inputs and bottom sheets, use react-native-keyboard-controller (KeyboardProvider at the root, KeyboardAwareScrollView for forms, KeyboardStickyView or useKeyboardHandler for a composer); it reads the same keyboard frames on both platforms.
  5. Keep safe-area handling separate: use react-native-safe-area-context insets for the home indicator and nav bar, and don't add them on top of the keyboard height.

TOOLS: THEN → NOW

windowSoftInputMode adjustResize plus react-native-keyboard-aware-scroll-viewEdge-to-edge insets plus react-native-keyboard-controller (requires Reanimated)
Hard-coded bottom padding and status bar heightsreact-native-safe-area-context insets and the keyboard's live height

PATTERN SNAPSHOT

import { KeyboardAwareScrollView, KeyboardProvider } from "react-native-keyboard-controller";

export function App() {
  return <KeyboardProvider><Navigation /></KeyboardProvider>;
}

// A long form: scrolls the focused input into view with 24px clearance.
function SignupForm() {
  return (
    <KeyboardAwareScrollView bottomOffset={24} keyboardShouldPersistTaps="handled">
      <EmailField /><PasswordField /><SubmitButton />
    </KeyboardAwareScrollView>
  );
}

CLOSE THE AI. EXPLAIN THIS.

Why did a screen that worked with adjustResize start hiding inputs after raising targetSdk to 35, without any JavaScript change?

SOURCES

Guide reviewed