Skip to content

Conversation

@mhoran
Copy link
Contributor

@mhoran mhoran commented Jan 4, 2026

Summary:

In iOS 26, backgrounding an app triggers an app snapshot [1], which will be taken in all supported device orientations. When in landscape mode, the OS will make a layout pass in portrait followed by another in landscape (and vice versa), taking a snapshot of each.

If scrolled to the bottom of a ScrollView in landscape mode, the content offset will be incorrect on resume, as UIScrollView updates the offset during the portrait layout pass to prevent overscroll. When the next layout pass is made, the offset is not reset to the original value.

Store the content offset on update when foregrounded. When backgrounded, override the content offset with the stored content offset, clamped to the content size. When the second snapshot is taken (in the original orientation), the original content offset is restored.

Fixes #54979.

[1] https://developer.apple.com/documentation/uikit/preparing-your-ui-to-run-in-the-background#Prepare-your-UI-for-the-app-snapshot

Changelog:

[IOS] [FIXED] - Scroll position not maintained after resume on iOS

Test Plan:

Reproducer: https://snack.expo.dev/@mhoran/restless-green-graham-crackers

Per #54979:

  1. Run the reproducer on an iPad simulator with patch applied
  2. Rotate the screen to landscape (app must be fullscreen)
  3. Scroll to the bottom
  4. Background the app
  5. Wait a few seconds
  6. Open the app
  7. See that the ScrollView position remains the same

Without this patch, the ScrollView position will change, due to the background snapshot taken in portrait mode.

Screen recording: https://drive.google.com/file/d/1WrEXNSF2dcYswtKrlM6YJglGiOzoGq8u/view?usp=drive_link.

In iOS 26, backgrounding an app triggers an app snapshot [1], which will
be taken in all supported device orientations. When in landscape mode,
the OS will make a layout pass in portrait followed by another in
landscape (and vice versa), taking a snapshot of each.

If scrolled to the bottom of a ScrollView in landscape mode, the content
offset will be incorrect on resume, as UIScrollView updates the offset
during the portrait layout pass to prevent overscroll. When the next
layout pass is made, the offset is not reset to the original value.

Store the content offset on update when foregrounded. When backgrounded,
override the content offset with the stored content offset, clamped to
the content size. When the second snapshot is taken (in the original
orientation), the original content offset is restored.

[1] https://developer.apple.com/documentation/uikit/preparing-your-ui-to-run-in-the-background#Prepare-your-UI-for-the-app-snapshot
@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 Jan 4, 2026
@facebook-github-bot facebook-github-bot added the Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team. label Jan 4, 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.

Scroll position not maintained after resume on iOS

2 participants