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
Conversation
…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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
On Android, the base
PDFViewcallsrecycle()inonDetachedFromWindow, which resetszoom,currentXOffset, andcurrentYOffset.PdfView.onAttachedToWindowthen reloads the document viadrawPdf(), which lands at the top ofdefaultPage.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): snapshotgetZoom(),getCurrentXOffset(),getCurrentYOffset()and the currentpathbefore callingsuper, where the base class recycles. Only taken when the view isn't already recycled.loadComplete: if a snapshot exists and thepathis unchanged, restore the viewport (zoomTo→moveTo→loadPages()).The restore is
post()-ed deliberately: the base class's internalloadCompleteinvokes theonLoadcallback beforejumpTo(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.