Skip to content

fix(ios): prevent SwiftUI keyboard avoidance from shrinking pages#1097

Closed
wonhyunkwon wants to merge 1 commit into
callstack:masterfrom
wonhyunkwon:fix/ios-swiftui-keyboard-avoidance
Closed

fix(ios): prevent SwiftUI keyboard avoidance from shrinking pages#1097
wonhyunkwon wants to merge 1 commit into
callstack:masterfrom
wonhyunkwon:fix/ios-swiftui-keyboard-avoidance

Conversation

@wonhyunkwon

Copy link
Copy Markdown

Summary

Fixes #1096. Possibly also addresses #1056.

Since v8 the iOS implementation is a SwiftUI TabView, which applies automatic keyboard avoidance by default: when the keyboard appears, the keyboard safe area shrinks the TabView's content, so every page is resized natively, outside of React Native's layout.

In a React Native app layout is fully owned by Yoga/Fabric, and keyboard handling is done at the RN level (KeyboardAvoidingView, @gorhom/bottom-sheet keyboard behaviors, etc.). The result is a double adjustment: the RN side already compensates for the keyboard, then SwiftUI shrinks the pages again, leaving a blank strip above the keyboard where page content should be. All RN layout values (onLayout) stay correct the whole time — only the native frames shrink, which makes this very hard to debug from the JS side.

Extensions.swift already neutralizes safe area influence for the hosting controller (disableSafeArea() overrides safeAreaInsets to .zero), but SwiftUI's keyboard avoidance is driven by the keyboard safe area channel, which that override does not cover.

The fix is one line: opt the TabView out of keyboard avoidance with .ignoresSafeArea(.keyboard). This restores the correct semantics for an RN-managed view — native views should follow the RN-driven frame only.

Note: this only reproduces on real devices; simulators behave differently with SwiftUI keyboard avoidance (hardware-keyboard integration), which is likely why it slipped through.

Test Plan

What's required for testing (prerequisites)?

  • A real iOS device (reproduction is not possible on simulators)
  • Any screen where the keyboard can open while a PagerView is visible — e.g. a TextInput above a PagerView (a bottom sheet with a search input works well)

What are the steps to reproduce (after prerequisites)?

  1. Open the screen containing the PagerView.
  2. Focus the TextInput so the keyboard appears.
  3. Before this fix: the pages shrink by roughly the keyboard height even though the pager's RN layout is unchanged — a blank strip appears above the keyboard (giving each layer a distinct backgroundColor shows the strip is the PagerView's own background where the natively-shrunken pages should be).
  4. After this fix: pages keep their RN-driven size; content fills right up to the keyboard.

Verified in a production app (RN 0.83.4, new architecture):

  • iPhone 15 Pro (real device): blank strip gone, pages keep RN-driven size with the keyboard open
  • iPhone 16 Plus simulator (iOS 18.6) and iPhone 16 Plus simulator (iOS 26.1): no regression — behavior unchanged

bun typescript, bun lint, and bun test all pass (native-only change).

Compatibility

OS Implemented
iOS
Android

Checklist

  • I have tested this on a device and a simulator
  • I added the documentation in README.md (not applicable — no API change)
  • I updated the typed files (TS and Flow) (not applicable — native-only change)

@troZee

troZee commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator

This PR is probably duplicated by this https://github.com/callstack/react-native-pager-view/pull/1085/changes

@troZee

troZee commented Jul 10, 2026

Copy link
Copy Markdown
Collaborator

Closed in favour of #1085

@troZee troZee closed this Jul 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[iOS] v8 (SwiftUI TabView): pages shrink when the keyboard appears — real devices only

2 participants