iOS: keep the library grid in its column after an edge-swipe back (#98) #31

Merged
backmeupplz merged 2 commits from fix/98-grid-leading-offset into main 2026-10-13 05:02:06 +00:00
backmeupplz commented 2026-10-13 03:37:05 +00:00 (Migrated from github.com)

Fixes agentboard #98.

What was wrong

On iOS 26 (the macos-26 runner's iOS 26.5 simulator), an edge-swipe back from details to a scrolled Library grid leaves the grid drawn 16pt to the left: the anchor tile's minX goes from 16 to 0 and stays there while the app is idle. The 16pt is CardGrid's inner .padding(16). ListLifecycle only checked minY, so it never caught this. iOS 27 simulators don't show it.

Evidence (throwaway lab PR #29, iOS 26.5 CI):

  • Current padding: 10/10 edge-swipe pops settled at x=0, and were still at x=0 5s later.
  • Same probe with the 16pt as scroll content margins: 0/10 shifted.
  • A programmatic .topLeading scroll to a tile didn't shift either variant, so the trigger is the interactive pop, not a scrollTo.
  • The CI log from the original failure (#97) shows the app idle and answering accessibility queries after the pop, so the shifted frame was a settled state, not a hung app.

Change

  • CardGrid no longer pads itself. Its three scroll views (Library, Favorites, Shelf) use .contentMargins(16, for: .scrollContent), which gives the same layout.
  • ListLifecycle now also asserts the anchor title's frame.minX after each return (button, edge swipe, button, and the filtered list).

Tests

  • Local (Xcode 27, iOS 27 iPhone 17 sim): ListLifecycle and OfflineLibrary pass.
  • CI runs the full suites on iOS 26.5.
Fixes agentboard #98. ## What was wrong On iOS 26 (the `macos-26` runner's iOS 26.5 simulator), an edge-swipe back from details to a scrolled Library grid leaves the grid drawn 16pt to the left: the anchor tile's `minX` goes from 16 to 0 and stays there while the app is idle. The 16pt is `CardGrid`'s inner `.padding(16)`. `ListLifecycle` only checked `minY`, so it never caught this. iOS 27 simulators don't show it. Evidence (throwaway lab PR #29, iOS 26.5 CI): - Current padding: **10/10** edge-swipe pops settled at x=0, and were still at x=0 5s later. - Same probe with the 16pt as scroll content margins: **0/10** shifted. - A programmatic `.topLeading` scroll to a tile didn't shift either variant, so the trigger is the interactive pop, not a `scrollTo`. - The CI log from the original failure (#97) shows the app idle and answering accessibility queries after the pop, so the shifted frame was a settled state, not a hung app. ## Change - `CardGrid` no longer pads itself. Its three scroll views (Library, Favorites, Shelf) use `.contentMargins(16, for: .scrollContent)`, which gives the same layout. - `ListLifecycle` now also asserts the anchor title's `frame.minX` after each return (button, edge swipe, button, and the filtered list). ## Tests - Local (Xcode 27, iOS 27 iPhone 17 sim): `ListLifecycle` and `OfflineLibrary` pass. - CI runs the full suites on iOS 26.5.
backmeupplz commented 2026-10-13 03:40:27 +00:00 (Migrated from github.com)

Independent review of exact head 5b7407e5f1: APPROVE, no required issues. It confirmed all three CardGrid call sites have the margins, the column layout and the 16pt top/bottom inset are unchanged, loadingFeedback/searchable/refreshable/scrollPosition behave the same, no UI test assumes x=16, and the new minX assertions are stable. Optional and not done here: a minX check in OfflineSeries for Shelf.

Independent review of exact head 5b7407e5f169a7502e8d5d931bd25c389d93f82b: **APPROVE**, no required issues. It confirmed all three `CardGrid` call sites have the margins, the column layout and the 16pt top/bottom inset are unchanged, `loadingFeedback`/`searchable`/`refreshable`/`scrollPosition` behave the same, no UI test assumes x=16, and the new `minX` assertions are stable. Optional and not done here: a `minX` check in `OfflineSeries` for Shelf.
Sign in to join this conversation.
No description provided.