Repository navigation
fix(collection): return to the viewed Pokédex page and catch log row after Back - #435
Merged
chattymin merged 10 commits intoOct 16, 2026
Merged
Conversation
DexScrollPager.page(containing:in:pageSize:) returns the page that shows a species, or 0 when it is nil or filtered out. Not wired up yet; the next commit uses it to return to the viewed page after Back. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The detail page replaces the grid, so Back rebuilt DexGridView and its page state started over at page 1. CollectionView now remembers the species whose detail page was closed and the rebuilt grid starts with it selected, deriving the page from that selection. Opening a species from a Home sprite now also lands on its page on Back. The anchor is used once, so a later rebuild (segment switch) still starts on page 1. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The catch log sits in the same branch the detail page replaces, so Back scrolled it to the top. The row that opened the detail page is now scrolled back to the center. The scroll waits one turn after the log appears: before the first layout the lazy rows above it are estimated and the scroll stopped short of the row. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Sample-data renders of the real CollectionView for the PR. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
CI showed the restored log stopping a row short of the row that opened the detail page. The first scrollTo places the target with estimated heights for the lazy rows; once the rows it reveals are measured they push the target off its spot. Scroll again after that layout pass. A single scroll fails the test locally too. The tests also retry a press until the screen changes: right after a transition the view tree can still hit-test the previous screen, which made a Back press miss on CI. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…he grid Back always stored the closed species as the grid's return anchor, but only the grid's onAppear clears it. When Back returned to the catch log (the detail page was opened from a log row, or from a Home sprite while the log segment was selected), the anchor stayed, and the next switch to the Pokédex segment opened on that species' page with it selected instead of page 1. testBackToTheLogLeavesTheGridOnItsFirstPage covers that path and fails when the anchor is stored unconditionally again. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… the species The grid found its return page by starting with the closed species as its selection. That brought back the selection border and the footer line, which nothing had shown since the detail page started replacing the grid (chattymin#264), and made the grid behave unlike the catch log, which only scrolls back to the row. DexGridView now keeps the anchor in its own state and uses it only to pick the page. testBackFromDetailReturnsToThePageOfThatSpecies asserts that the footer does not name the species and fails when the anchor selects it again. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Sample-data render of the real CollectionView after Back: page 2 with no species selected. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Owner
|
Thank you for your contribution! |
5 of 10 tasks
KillianHzr
added a commit
to KillianHzr/PokeTokenLBI
that referenced
this pull request
Oct 19, 2026
…GridView init Upstream chattymin#435 gave DexGridView an explicit init, which dropped the evolutionFamily property added by this branch.
7 of 10 tasks
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.
Summary
Back from a Pokédex detail page always landed on page 1 of the grid, even when the species was opened from page 3. The catch log had the same problem: Back scrolled it to the top.
Why:
CollectionViewswaps the grid/log out forPokemonDetailViewwith an if/else. Opening a detail page unmountsDexGridView, which drops its@State page. Back mounts a fresh grid on page 1. The filters survived because they live one level up, inCollectionView.Fix:
CollectionViewremembers what the detail page was opened from and hands it to the rebuilt view once.DexScrollPager.page(containing:in:pageSize:)). Nothing is selected, the same as the catch log. The page follows the species, not a page number, so:scrollToplaces the row using estimated heights for the lazy rows, and once the rows it reveals are measured the target shifts (one row short on CI). The second scroll runs after that layout pass.scrollPosition(id:)was tried too: withoutanchor:(macOS 14) it overshot the end of the list and left the log blank.Commits are split as: pure page lookup + tests → Pokédex fix → catch log fix → defect-log entry → PR images → catch log correction from the first CI run (+ its defect-log note) → grid anchor set only when Back lands on the grid → grid anchor split from the selection (+ re-rendered image).
Type of change
UI changes
Sample-data renders of the production
CollectionView(offline fixture, so the detail page shows its "could not be loaded" state). The "Before" column is the state Back produced before this change: a freshly built grid/log, rendered from the same fixture.Pokédex: open #18 Pidgeot (page 2), e.g. from its Home sprite, then press Back.
Catch log: scroll down, open Butterfree's entry, then press Back.
Checklist
swift buildandswift testpass locallyTests
DexScrollPagerTests: page lookup for first/last page, the 16th/17th boundary, nil, and filtered-out IDs.DexBackNavigationTests(new): hosts the realCollectionViewin a window, does the detail → Back round trip, and reads the result off the rendered pixels with Vision. The accessibility tree is empty without an AX client, so it can't be used here. Each guard was checked by injecting the defect: removing the anchor, the one-time use, the log anchor, or the second log scroll, keeping the grid anchor after a Back to the log, or letting the anchor select the species each makes a test fail. Presses retry until the screen changes, because right after a transition the view tree can still hit-test the previous screen (a missed Back press on the first CI run).llvm-cov show, no^0).SessionKeySettingsRenderingTests, thenSpriteImageCacheTests/UnownSpriteCacheTests). They pass alone and together with the new tests.test-gate.shcouldn't locate the test binary under Xcode's Swift 6.4 build layout, so the coverage numbers above come from running itsllvm-cov reportstep by hand. CI runs the gate as usual.🤖 Generated with Claude Code