[iOS] Toggling "Page Fitting" (Fit / Fill) causes document to jump back one page
Component: Document Viewer / Reading Settings (iPadOS)
Severity: Medium (Functional / Navigation regression)
Version: 2.0.7 (build 461)
Repro video: https://github.com/user-attachments/assets/42071e45-b200-4f3a-98db-a1eca3b4488b
> This is the second of a few bug reports. Each on its own is minor, but together they add up to a rough experience on iOS, which is otherwise working beautifully.
>
> AI assisted in drafting this report, but the observations come from real use of the app. Code references were located and reviewed to support the described behavior.
Summary
In the view settings popover, toggling the "Page Fitting" option between "Fit" and "Fill" unexpectedly navigates backward to the previous page rather than maintaining the current page position.
Steps to reproduce
1. Open a multi-page document/PDF (e.g., navigate to page 14).
2. Tap the reading/view options icon in the top toolbar to open the settings menu.
3. Locate the "Page Fitting" section (Fit / Fill toggle).
4. Repeatedly tap between "Fit" and "Fill".
Expected
The viewer toggles the zoom/aspect ratio mode (fitting to window vs. filling screen) while keeping the user on the currently viewed page (e.g., remaining on page 14).
Actual
Every time the setting is toggled between Fit and Fill, the reader jumps backward by one page (e.g., from page 14 to 13 to 12 to 11 to 10), losing the reader's place in the document.
Related issues
- #434 "Improve PDF settings" (CLOSED) — the origin issue that added the Page Fitting setting to the settings popover. BUG-002 is a quality gap in the resulting implementation. https://github.com/zotero/zotero-ios/issues/434
Related forum threads
No exact forum match found for the "toggling Fit/Fill jumps back a page" behavior specifically. General Page Fitting / page-spread discussion (without this exact symptom) can be found under the page fitting and iOS page spreads threads.
https://forums.zotero.org/search?Search=page+fitting
https://forums.zotero.org/discussion/comment/463104
Relevant code
The toggle propagates from the settings popover to the reader view model to pdfController.updateConfiguration, which relayouts the spread/page grid. The .settings branch is the only page-affecting code path in PDFDocumentViewController that mutates the layout without saving/restoring the current page index, unlike .visiblePageFromThumbnailList and .initialDataLoaded, both of which preserve the page.
- Zotero/Scenes/General/Views/ReaderSettingsViewController.swift — .pageFitting row (Fit/Fill/Automatic segmented control); dispatches .setPageFitting(...).
- Zotero/Scenes/General/ViewModels/ReaderSettingsActionHandler.swift — .setPageFitting only mutates state.
- Zotero/Scenes/Detail/PDF/Views/PDFReaderViewController.swift — showSettings(sender:) re-emits settings state as .setSettings.
- Zotero/Scenes/Detail/PDF/Views/PDFDocumentViewController.swift — update(state:pdfController:), .settings branch: calls pdfController.updateConfiguration (relayouts) with no setPageIndex save/restore and no backForwardList.register. Contrast .visiblePageFromThumbnailList in the same file, which does save/restore pageIndex.
- Zotero/Scenes/Detail/PDF/ViewModels/PDFReaderActionHandler.swift — set(...) / setVisiblePage: the relayout-driven pageIndexPublisher emission updates state.visiblePage but sets state.changes = .visiblePage (or .visiblePageFromDocument), neither of which PDFDocumentViewController acts on to scroll back, so the shifted page sticks.
AI assessment
An AI assistant reviewed the codebase and believes a fix is possible. Its recommendation: in the .settings branch of PDFDocumentViewController.update(state:pdfController:), capture pdfController.pageIndex before pdfController.updateConfiguration and restore it afterward via setPageIndex + backForwardList.register, mirroring the existing .visiblePageFromThumbnailList pattern in the same file. It flags one caveat to verify: updateConfiguration may be asynchronous and pageIndexPublisher fires during/after the relayout, which could race the restore, so the timing of the restore needs care. I have not verified this recommendation.
Severity: Medium (Functional / Navigation regression)
Version: 2.0.7 (build 461)
Repro video: https://github.com/user-attachments/assets/42071e45-b200-4f3a-98db-a1eca3b4488b
> This is the second of a few bug reports. Each on its own is minor, but together they add up to a rough experience on iOS, which is otherwise working beautifully.
>
> AI assisted in drafting this report, but the observations come from real use of the app. Code references were located and reviewed to support the described behavior.
Summary
In the view settings popover, toggling the "Page Fitting" option between "Fit" and "Fill" unexpectedly navigates backward to the previous page rather than maintaining the current page position.
Steps to reproduce
1. Open a multi-page document/PDF (e.g., navigate to page 14).
2. Tap the reading/view options icon in the top toolbar to open the settings menu.
3. Locate the "Page Fitting" section (Fit / Fill toggle).
4. Repeatedly tap between "Fit" and "Fill".
Expected
The viewer toggles the zoom/aspect ratio mode (fitting to window vs. filling screen) while keeping the user on the currently viewed page (e.g., remaining on page 14).
Actual
Every time the setting is toggled between Fit and Fill, the reader jumps backward by one page (e.g., from page 14 to 13 to 12 to 11 to 10), losing the reader's place in the document.
Related issues
- #434 "Improve PDF settings" (CLOSED) — the origin issue that added the Page Fitting setting to the settings popover. BUG-002 is a quality gap in the resulting implementation. https://github.com/zotero/zotero-ios/issues/434
Related forum threads
No exact forum match found for the "toggling Fit/Fill jumps back a page" behavior specifically. General Page Fitting / page-spread discussion (without this exact symptom) can be found under the page fitting and iOS page spreads threads.
https://forums.zotero.org/search?Search=page+fitting
https://forums.zotero.org/discussion/comment/463104
Relevant code
The toggle propagates from the settings popover to the reader view model to pdfController.updateConfiguration, which relayouts the spread/page grid. The .settings branch is the only page-affecting code path in PDFDocumentViewController that mutates the layout without saving/restoring the current page index, unlike .visiblePageFromThumbnailList and .initialDataLoaded, both of which preserve the page.
- Zotero/Scenes/General/Views/ReaderSettingsViewController.swift — .pageFitting row (Fit/Fill/Automatic segmented control); dispatches .setPageFitting(...).
- Zotero/Scenes/General/ViewModels/ReaderSettingsActionHandler.swift — .setPageFitting only mutates state.
- Zotero/Scenes/Detail/PDF/Views/PDFReaderViewController.swift — showSettings(sender:) re-emits settings state as .setSettings.
- Zotero/Scenes/Detail/PDF/Views/PDFDocumentViewController.swift — update(state:pdfController:), .settings branch: calls pdfController.updateConfiguration (relayouts) with no setPageIndex save/restore and no backForwardList.register. Contrast .visiblePageFromThumbnailList in the same file, which does save/restore pageIndex.
- Zotero/Scenes/Detail/PDF/ViewModels/PDFReaderActionHandler.swift — set(...) / setVisiblePage: the relayout-driven pageIndexPublisher emission updates state.visiblePage but sets state.changes = .visiblePage (or .visiblePageFromDocument), neither of which PDFDocumentViewController acts on to scroll back, so the shifted page sticks.
AI assessment
An AI assistant reviewed the codebase and believes a fix is possible. Its recommendation: in the .settings branch of PDFDocumentViewController.update(state:pdfController:), capture pdfController.pageIndex before pdfController.updateConfiguration and restore it afterward via setPageIndex + backForwardList.register, mirroring the existing .visiblePageFromThumbnailList pattern in the same file. It flags one caveat to verify: updateConfiguration may be asynchronous and pageIndexPublisher fires during/after the relayout, which could race the restore, so the timing of the restore needs care. I have not verified this recommendation.
Upgrade Storage