Skip to content

[ScrollView][iOS] Change padding to use max of safe area inset/container value - #59836

Draft
huntie wants to merge 1 commit into
pr59194from
pr59836
Draft

huntie wants to merge 1 commit into
pr59194from
pr59836

Conversation

@huntie

@huntie huntie commented Nov 6, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Context

Optional but intended follow-up to #59194.

#59194 fixed the documented behaviour of ScrollView/FlatList contentInsetAdjustmentBehavior by handling safe area padding across the scrollable axis, such as the rail on iPhone Duo and the notch on a regular iPhone in landscape.

This diff

Proposes a further update to contentInsetAdjustmentBehavior and how it interacts with padding set by contentContainerStyle.

image

The lowdown: This PR moves from an "add padding" approach to "use greatest of padding or safe area", per edge.

The aim is to make React Native's scroll views work intuitively:

  • This is a hard thing for most devs to spot and remember to do. To get a high quality result requires negating the extra padding on one edge manually (i.e. Add StatusBar.getVerticalBarEdgeIOS and useVerticalBarEdgeIOS for iPhone Duo #59237).
  • Our historic "add padding" handling in iPhone landscape is arguably a bug. From our own ScrollView RNTester demos in landscape, having added horizontal padding beyond the safe area on both sides misaligns the content from relative UI such as the header nav bar.
    • This is also how UIKit treats layout margins against the safe area.

Changes

Make the safe area a floor on the container's padding rather than an addition: an edge takes the larger of its contentContainerStyle padding and the inset. This keeps content aligned with the safe area edge instead of leaving a second gutter under the rail or beside the notch.

  • A padding: 20 container on a folded iPhone Duo keeps 20 pt on the open side and sits at the rail on the other, where it had the rail plus 20 pt.
  • Along the scrollable axis UIKit's content inset stays, and the container's padding on those edges is reduced by that inset, floored at zero, so the content lands on the same floor. A navigation bar is part of that inset.
  • A percentage padding still keeps its edge as styled, with no inset.
  • The RNTester full screen example gains a 20 pt padding on its content container to show the clamp.
    Android is untouched: its scroll view has no safe area handling across the scrollable axis to clamp.

Changelog:
[iOS][Breaking] - ScrollView: contentInsetAdjustmentBehavior now pads content by the larger of the safe area or contentContainerStyle padding. Previously, it added the two.

Test Plan

ReactCommon/react/renderer/components/scrollview/tests/ScrollContentViewTest.cpp

RNTester, ScrollView > Content Inset Adjustment Behavior, full screen modal under automatic, with padding: 20 on the content container (added to the example in this PR). Before is the stack base #59194 with the same example change; after is this PR.

iPhone Duo folded, before iPhone Duo folded, after
Rows stop 20 pt short of the rail: the inset and the padding add ✅ Rows sit at the rail, with the 20 pt kept on the open side
iPhone Duo folded, end of the list, before after
The last row stops 20 pt above the bottom inset ✅ The last row sits at the bottom inset
iPhone 18 Pro portrait, before after
The header sits 20 pt below the status bar inset ✅ The header sits at the status bar inset
iPhone 18 Pro portrait, end of the list, before after
The last row stops 20 pt above the home indicator inset ✅ The last row sits at the home indicator inset
iPhone 18 Pro landscape, before after
Rows sit 20 pt inside both safe area edges ✅ Rows sit at both safe area edges, and the 20 pt stays at the top, which has no inset in landscape

@huntie
huntie changed the base branch from main to pr59194 November 6, 2026 21:37
@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Nov 6, 2026
@huntie
huntie added this pull request to stack #59837 November 6, 2026 21:37

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. p: Expo Partner: Expo Partner

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant