Skip to content

fix(reader): defer zoom state writes out of gesture callbacks - #960

Merged
everpcpc merged 2 commits into
mainfrom
fix/divina-zoom-gesture-crash
Aug 22, 2026
Merged

fix(reader): defer zoom state writes out of gesture callbacks#960
everpcpc merged 2 commits into
mainfrom
fix/divina-zoom-gesture-crash

Conversation

@everpcpc

Copy link
Copy Markdown
Owner

Summary

Fixes the DIVINA reader crashes on iPadOS 18 reported in #958, where the app crashed on the first pinch-to-zoom gesture and on subsequent tap/drag gestures.

Root Cause

scrollViewDidZoom in the paged DIVINA reader (NativePagedPageContentView) and the Page Curl reader (NativeImagePageViewController) published viewModel.isZoomed synchronously from inside the scroll view's zoom gesture callback. This triggers a SwiftUI re-render chain (DivinaReaderView re-renders → controls hide → updateUIView → slot content reconfigure/layout) while the pinch gesture is still in flight — a state publication pattern that crashes AttributeGraph on iOS 18. PageScrollView already defers this write via DispatchQueue.main.async; these two zoom hosts were missing that guard.

Changes

  • Defer the isZoomed write to the next runloop in both remaining zoom hosts (with a stale-value recheck), matching the existing PageScrollView pattern.
  • Skip zoom-scale resets in NativePagedPageContentView.resetScrollViewportState() while a pinch gesture is .began/.changed, retrying on the next runloop until the gesture settles. Resetting the scale mid-gesture desyncs UIScrollView's internal gesture state. (iOS only; pinchGestureRecognizer is unavailable on tvOS, where zoom is not user-driven anyway.)

Validation

  • make build-ios / make build-macos / make build-tvos all pass.
  • Not yet verified on a physical iPadOS 18 device; a crash log from the reporter (Settings → Privacy & Security → Analytics & Improvements → Analytics Data) would help confirm the exact stack.

Publishing isZoomed synchronously from scrollViewDidZoom runs while the
pinch gesture is still active, which can crash SwiftUI AttributeGraph on
iOS 18 (issue #958). Defer the observable write to the next runloop in
NativePagedPageContentView and NativeImagePageViewController, matching the
existing pattern in PageScrollView, and skip zoom-scale resets while a
pinch gesture is in flight.
@everpcpc
everpcpc marked this pull request as ready for review August 22, 2026 13:32
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

@everpcpc
everpcpc merged commit 5c30702 into main Aug 22, 2026
3 checks passed
@everpcpc
everpcpc deleted the fix/divina-zoom-gesture-crash branch August 22, 2026 13:38
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