Skip to content

fix(ios): keep tab screens hidden until their stack is sized - #349

Merged
samuelloranger merged 4 commits into
mainfrom
fix/ios-first-layout-width
Oct 18, 2026
Merged

samuelloranger merged 4 commits into
mainfrom
fix/ios-first-layout-width

Conversation

@samuelloranger

Copy link
Copy Markdown
Owner

Problem

On a cold launch, and on the first visit to a tab, screens drew a squeezed layout for a few frames before snapping to full width. Home's hero title wrapped word by word and the Pipeline card stacked one letter per line. Find showed "No results for these filters" in a narrow column, fading into the grid. #348 removed the crossfade that had been blurring these frames together, so they became more visible.

Measuring the layout showed the cause: the tab container is full size from the first frame, but the navigation stack inside it hands its root a zero-size proposal for its first ~0.3 s. SwiftUI lays the content out against that and draws it.

Changes

  • Each tab root stays invisible until its navigation stack reports a real size (hiddenUntilSized(), applied in RootTabsView.tabRoot).
  • Find shows its skeleton until its first load settles instead of the "no results" state, and its empty and error states take the full width.
  • The Continue card paints its saved copy before the first frame. Painting it after the first frame, animated, slid Home's Pipeline card across it.
  • A DEBUG simulator launch with RAWKOON_SERVER and RAWKOON_TOKEN now signs in before the first frame, so it reproduces a signed-in device launch. Previously it passed through Login, which hid the bug on the simulator.

Verification

  • Recorded cold launches and first tab visits on the simulator against a live server before and after, and checked them frame by frame: no zero-size frames, no overlap between the Continue and Pipeline cards, no "no results" flash in Find.
  • iOS check scripts, swiftformat --lint, and swiftlint (no errors).
  • macbuild build and full test run passed.
  • Installed on a physical device for a hands-on check.

A navigation stack lays its root out at zero size for its first frames,
on a cold launch and on the first visit to a tab. SwiftUI drew that
layout, so Home's hero and Pipeline card, and Find's empty state,
showed squeezed into a sliver before snapping to full width. Each tab
root now stays invisible until its stack reports a real size.

Find showed "No results for these filters" before its first load had
started; it now shows the skeleton until that load settles, and its
empty and error states take the full width. The Continue card paints
its saved copy before the first frame instead of animating it in
afterwards, which slid Home's Pipeline card across it.

A DEBUG simulator launch with RAWKOON_SERVER and RAWKOON_TOKEN now
signs in before the first frame, so it reproduces a signed-in device
launch instead of passing through Login.
Five segments truncated their labels on a phone. The Activity tab now
offers Inbox, Requests, Calendar and History; the download queue opens
on its own screen from Home's Pipeline card, which was already its only
direct entry point. The French Inbox label becomes "Notifications" so
all four fit.
fix(ios): drop the Queue lane from the Activity picker
@samuelloranger
samuelloranger merged commit da1218d into main Oct 18, 2026
17 checks passed
@samuelloranger
samuelloranger deleted the fix/ios-first-layout-width branch October 18, 2026 02:25
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