Skip to content

[iOS] Account for contentInset in Fabric maintainVisibleContentPosition autoscroll#56672

Open
enahum wants to merge 1 commit intofacebook:mainfrom
enahum:fix/ios-maintain-visible-content-position-content-inset
Open

[iOS] Account for contentInset in Fabric maintainVisibleContentPosition autoscroll#56672
enahum wants to merge 1 commit intofacebook:mainfrom
enahum:fix/ios-maintain-visible-content-position-content-inset

Conversation

@enahum
Copy link
Copy Markdown
Contributor

@enahum enahum commented May 3, 2026

Summary

The Fabric implementation of _adjustForMaintainVisibleContentPosition in RCTScrollViewComponentView.mm does not account for contentInset when computing the autoscroll threshold comparison or the scroll target position. The Paper implementation (RCTScrollView.m) already handles this correctly via bottomInset/leftInset variables. The Fabric port simply missed carrying this logic over.

Root cause

Vertical (before):

CGFloat y = _scrollView.contentOffset.y;              // ignores contentInset
[self scrollToOffset:CGPointMake(..., 0) animated:YES]; // wrong target

Vertical (after, matching Paper):

CGFloat bottomInset = [self isInverted] ? _scrollView.contentInset.top : _scrollView.contentInset.bottom;
CGFloat y = _scrollView.contentOffset.y + bottomInset; // inset-adjusted
[self scrollToOffset:CGPointMake(..., -bottomInset) animated:YES]; // correct target

Same pattern for the horizontal branch with leftInset.

Visible symptoms

On a scroll view with a non-zero contentInset:

  1. Wrong threshold firing: The autoscroll threshold comparison uses raw contentOffset instead of the inset-adjusted value, causing autoscroll to fire when it should not (or fail to fire when it should).
  2. Wrong scroll target: When autoscroll fires, scrollToOffset is called with 0 instead of -inset, causing the scroll view to jump to the wrong position.

The same scroll view behaves correctly on Paper (Old Architecture) since RCTScrollView.m already accounts for contentInset.

No behavior change when contentInset is zero.

Changelog:

[iOS] [Fixed] - Account for contentInset in Fabric ScrollView maintainVisibleContentPosition autoscroll threshold and target

Test Plan

  • Non-inverted vertical, contentInset={{ bottom: 100 }}, autoscrollToTopThreshold: 10: insert item at index 0 while at the bottom → stays at correct position, does not jump to y=0
  • Inverted vertical, contentInset={{ top: 100 }}, autoscrollToTopThreshold: 10: insert item at index 0 while at the bottom → stays at contentOffset.y = -100, does not jump to y=0
  • Both cases, scrolled past the threshold: insert item → no autoscroll fires
  • Non-inverted horizontal, contentInset={{ left: 100 }}: equivalent checks
  • Inverted horizontal, contentInset={{ right: 100 }}: equivalent checks
  • All cases with contentInset all zeros: existing behavior unchanged
  • Run existing ScrollView tests: yarn jest packages/react-native/Libraries/Components/ScrollView

…rollView

The Fabric implementation of `_adjustForMaintainVisibleContentPosition` did
not account for `contentInset` when computing the autoscroll threshold
comparison or the scroll target position, unlike the Paper implementation
(`RCTScrollView.m`) which already handles this correctly.

When a non-zero `contentInset` is set on a scroll view, two bugs occurred:

1. The threshold comparison used raw `contentOffset` instead of the
   inset-adjusted value, causing autoscroll to fire incorrectly.
2. The autoscroll target was hardcoded to `0` instead of `-inset`, causing
   the scroll view to jump to the wrong position.

Fix: compute `bottomInset`/`leftInset` (respecting `isInverted`) and use
them to adjust both the threshold comparison and the `scrollToOffset` target,
matching the existing Paper logic in `RCTScrollView.m`.

No behavior change when `contentInset` is zero.
@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 May 3, 2026
@facebook-github-tools facebook-github-tools Bot added the Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team. label May 3, 2026
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. Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant