Skip to content

fix(android): restore zoom and scroll offset when the view is re-attached to the window#1028

Open
JakobFelixJulius wants to merge 1 commit into
wonday:masterfrom
JakobFelixJulius:fix/android-restore-viewport-after-detach
Open

fix(android): restore zoom and scroll offset when the view is re-attached to the window#1028
JakobFelixJulius wants to merge 1 commit into
wonday:masterfrom
JakobFelixJulius:fix/android-restore-viewport-after-detach

Conversation

@JakobFelixJulius

@JakobFelixJulius JakobFelixJulius commented Jul 23, 2026

Copy link
Copy Markdown

Problem

On Android, the base PDFView calls recycle() in onDetachedFromWindow, which resets zoom, currentXOffset, and currentYOffset. PdfView.onAttachedToWindow then reloads the document via drawPdf(), which lands at the top of defaultPage.

So whenever the view is detached from the window without being unmounted — a react-navigation / react-native-screens screen pushed on top, a bottom-tab switch, a device rotation — the user loses their reading position and pinch zoom when they return to the PDF.

This is a long-standing pain point: #224, #275, #329, #380 all describe variants of it.

Fix

  • onDetachedFromWindow (new override): snapshot getZoom(), getCurrentXOffset(), getCurrentYOffset() and the current path before calling super, where the base class recycles. Only taken when the view isn't already recycled.
  • loadComplete: if a snapshot exists and the path is unchanged, restore the viewport (zoomTomoveToloadPages()).

The restore is post()-ed deliberately: the base class's internal loadComplete invokes the onLoad callback before jumpTo(defaultPage), so a synchronous restore would be immediately overwritten by that jump.

The path guard means a source change between detach and re-attach behaves exactly as before (fresh load, no restore). No API change, no new props; iOS is unaffected.

Testing

Tested in a production cruise-line app (React Native 0.86, new architecture/Fabric, expo-router with react-native-screens native stack) on Android: with this change, scroll position and pinch zoom survive another screen being stacked over the PDF viewer and closed again — previously the document reloaded at the top of the last page with zoom reset. By the same mechanism this should also cover the tab-switch and rotation reports in the linked issues.

…ched to the window

The base PDFView calls recycle() in onDetachedFromWindow, resetting zoom,
currentXOffset and currentYOffset. PdfView.onAttachedToWindow then reloads
via drawPdf(), landing at the top of defaultPage — so any detach without
unmount (a react-navigation screen stacked on top, a tab switch, a device
rotation) loses the user's reading position and zoom.

Snapshot the viewport before the base class recycles and restore it in
loadComplete after the re-attach reload. The restore is post()-ed because
the internal loadComplete fires the onLoad callback before
jumpTo(defaultPage); a synchronous restore would be overwritten. The saved
path guards against the source changing between detach and re-attach.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant