Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

ScrollView maintainVisibleContentPosition applies the anchor delta to the already-clamped offset when content shrinks (iOS + Android, Fabric)

未关闭
#58,578 1 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

评估

难度
4/5
预计耗时
3-5 天
新手友好度
68/100
Issue 类型
缺陷
描述清晰度
基本清楚
活跃度
活跃
技术栈
react-native
领域
mobile-dev

调研方向

从链接的 rn-mvcp-shrink reproducer 开始,检查 Android 的 MaintainVisibleScrollPositionHelper.updateScrollPositionInternal() 以及 iOS 的 RCTScrollViewComponentView._adjustForMaintainVisibleContentPosition()。在两个平台上重现 shrink 情况,并跟踪 prepare、clamp 和 anchor-update 的顺序。当新内容允许时,被锚定的子元素能够保持其屏幕位置,而确实无法到达的 offset 仍然会被 clamp,即表示完成。

由索引模型根据 Issue 内容生成。

描述

Component: ScrollView Needs: Triage :mag: Platform: Android Platform: iOS
Description

When a mount makes a ScrollView's content shorter such that the current contentOffset.y is past the new maximum scroll, both platforms clamp the offset during the mount and then add the anchor's delta to the already-clamped value. The anchor child is not maintained: the offset is driven below zero and clamps to 0, landing at the very top of the list.

The grow direction, using the same anchor and the same prop, is exact to the pixel on both platforms — which is what isolates the clamp ordering as the cause rather than the anchor measurement.

Android — MaintainVisibleScrollPositionHelper.updateScrollPositionInternal() reads scrollView.scrollY fresh after didMountItems, but ReactScrollView.onLayoutChange has already run in the same mount and done if (currentScrollY > maxScrollY) scrollTo(scrollX, maxScrollY).

iOS — RCTScrollViewComponentView._adjustForMaintainVisibleContentPosition() uses _scrollView.contentOffset.y + deltaY after updateState: has set the smaller contentSize, and UIKit clamps contentOffset the moment contentSize drops below it.

Both should apply the delta to the offset captured in the prepare step and clamp afterwards, not before. Both sites are unchanged on main as of filing.

Adjacent, possibly the same root cause: #52757 (maintainVisibleContentPosition scrolls when an item is removed from the head).

Steps to reproduce

Reproducer: https://github.com/muhasabahhub/rn-mvcp-shrink
A single ScrollView, 60 direct View children, no dependencies beyond expo/react/react-native. The on-screen header prints contentOffset.y, contentSize.height, the minIndexForVisible in effect, and the child currently at the top, with the pre-press values frozen beside the live ones.

SHRINK (the defect)

  1. Open the app — children start expanded (each carries an 8-line block).
  2. Scroll so child 44 is the first child under the header.
  3. Press Toggle once (each child loses its 8-line block).
  4. Observed: contentOffset.y is 0.0 and the child at top is 0 — about 45 children above the one the anchor named.

GROW (the control)

  1. Relaunch. Press Toggle once so the children are collapsed.
  2. Scroll so child 44 is the first child under the header.
  3. Press Toggle once (each child regains its 8-line block).
  4. Observed: child 44 is still at the top, exact.

Full measured numbers, both platforms, are in the repo's README.

Expected

The child at minIndexForVisible keeps its screen position when the content shrinks, as it does when it grows. Where the correct offset is reachable within the new content, the anchor should be maintained; only a target beyond the new maximum should clamp.

Actual

contentOffset.y is driven below zero and clamps to 0.0 — the list lands at the very top, about 45 children above the one the anchor named.

React Native Version

0.86.3

Affected Platforms

Runtime - Android, Runtime - iOS

Output of npx @react-native-community/cli info
OS: Windows 11 10.0.26200
Node: 24.13.1
npm: 11.19.0
expo: 57.0.23 (SDK 57, managed workflow)
react: 19.2.3
react-native: 0.86.3
Architecture: Fabric (new architecture — Expo SDK 57 default)

Devices:
- Samsung Galaxy S25, Android <fill in>, Expo Go
- iPhone 15, iOS 26.6.1, Expo Go

(react-native info is unavailable in this project — @react-native-community/cli is not a dependency of the bare repro. The above is from expo-env-info plus device details.)
Stacktrace or Logs
No crash or error; incorrect scroll position only.
MANDATORY Reproducer

https://github.com/muhasabahhub/rn-mvcp-shrink

Screenshots and Videos

Samsung S25:

Image Image Image Image

Iphone 15:

Image Image Image Image
主要语言
C++
星标
127k
派生
25.3k
PR 合并指标
30 天内没有已合并 PR

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

react/react-native 的其他 Issue

查看 react/react-native 的全部 Issue

相似的 Issue

更多 C++ Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。