fix(ios): stop the GeometryReader root from shrinking pages for the keyboard - #1150
Merged
troZee merged 2 commits intoSep 29, 2026
Merged
Conversation
…eyboard Since callstack#1101 the GeometryReader is the root of PagerView.body and every page is framed to its proxy size. It still honoured the keyboard safe-area region, so pages shrank by the keyboard overlap while React Native kept them at full height. Apply .ignoresSafeArea() to the root as well. Adds the Issue callstack#1096 Keyboard Shrink Repro example and a Maestro flow. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Contributor
Author
|
Heads-up: #1149 touches the same spot. It adds
cc @ArekChr |
There was a problem hiding this comment.
Copilot review overview
🟢 Approval recommended
The targeted fix is consistent with the SwiftUI layout hierarchy and is covered by a focused regression flow.
Review effort: Balanced
Findings: None
What changed in this PR
Prevents iOS SwiftUI keyboard avoidance from shrinking React Native-managed pager pages.
Changes:
- Makes the root
GeometryReaderignore safe areas. - Adds an iOS keyboard-shrink reproduction screen and Maestro regression test.
- Registers the reproduction in the example app.
| File | Description |
|---|---|
ios/PagerView.swift |
Prevents keyboard-driven page resizing. |
example/src/gh-issues/Issue1096KeyboardShrinkRepro.tsx |
Adds the reproduction screen. |
example/src/App.tsx |
Registers the new example. |
.maestro/setup/issue_1096_keyboard_shrink_repro_setup.yaml |
Opens the reproduction screen. |
.maestro/issues/issue_1096_keyboard_shrink_repro.yaml |
Verifies interaction before and after keyboard dismissal. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
troZee
enabled auto-merge (squash)
September 29, 2026 14:29
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Related to #1099 (keyboard variant, see comment). Follow-up to #1096, which regressed in 9.0.2.
On iOS, pages shrink natively when the keyboard opens, while React Native still lays them out at full height. Anything in the lower part of a page is clipped, and its native frame no longer matches the React Native layout, so taps miss it.
onLayoutkeeps reporting the full height, so nothing on the JS side can compensate.original
pager-before-fix.mp4
pager-after-fix.mp4
reproduction
pager-repro-unfixed.mp4
pager-repro-fixed.mp4
What happened
.ignoresSafeArea(.keyboard), but was closed in favour of fix(ios): propagate safe area insets to child UIKit views inside PagerView #1085, which only propagates safe-area insets to child UIKit views and has no keyboard handling.TabViewwas the root ofPagerView.body, and its.ignoresSafeArea()(all regions, keyboard included) covered the whole hierarchy.TabViewin aGeometryReaderfor the vertical layout and frames every page toproxy.size..ignoresSafeArea()stayed on theTabView, so the new root still honours the keyboard region. When the keyboard opens,proxy.size.heightdrops by the keyboard overlap and every page is framed to that.disableSafeArea()on the hosting view. That zeroessafeAreaInsetsonly; SwiftUI's keyboard avoidance is a separate channel, so it does not help here.Fix
Apply
.ignoresSafeArea()to theGeometryReaderroot as well. Layout is owned by React Native, so the pager should not react to the keyboard at all. The inner modifier on theTabViewstays, so the vertical-layout frames are unchanged.} } + .ignoresSafeArea() .onAppear {PageChildViewController.propagateSafeArea()reads insets from the RN screen view, not from the hosting view, so child UIKit insets (#1085, #1142) are unaffected.Test Plan
What's required for testing (prerequisites)?
iOS simulator or device, New Architecture. A pager inside a container that follows the keyboard with a transform (the common
KeyboardStickyView/ chat-composer setup). When the pager fills the screen the shrunk area sits under the keyboard, so the bug is invisible there.What are the steps to reproduce (after prerequisites)?
Added
Issue #1096 Keyboard Shrink Reproto the example app and.maestro/issues/issue_1096_keyboard_shrink_repro.yaml:last-row taps: 0).Verified
bun typescript,bun lintandbun testpass.pager_rtl_exampleandpager_vertical_basic_examplefail in the layout-direction setup step, before any pager code runs:DevSettings.reload()does not take effect in the Release build, so the direction never flips.pager_vertical_basic_examplepasses when run on its own. RTL is not verified.Found in a production app (chat mention picker built on
react-native-tab-view): on 9.0.5 only the first row of a page survived with the keyboard open; with this change the page matches React Native's layout. Android is untouched.Compatibility
Checklist
README.md: not applicable