Skip to content

Host the bottom bar in a navigation stack - #86

Merged
austin-smith merged 1 commit into
mainfrom
bottom-bar-navigation-host
Jul 20, 2026
Merged

austin-smith merged 1 commit into
mainfrom
bottom-bar-navigation-host

Conversation

@austin-smith

Copy link
Copy Markdown
Owner

What Changed

  • Wrap the iOS board in a NavigationStack that only ever hosts — it never pushes, and its own navigation bar is hidden so the board keeps the full screen.
  • Drive game-picker bar visibility through .toolbar(_:for: .bottomBar) instead of conditionally emptying the toolbar's item list.
  • Tighten the StockFrameKey / WasteFrameKey reducers to reject sizeless candidates (!next.isEmpty) rather than only the exact .zero rect.

macOS is unaffected: toolbarHost returns the view unchanged off iOS.

Why

The bottom toolbar items disappeared completely for a moment on every stock draw.

ContentView sits bare in the WindowGroup with no navigation container, so .bottomBar items were bridged onto the window root, where board mutations tore the bar down and rebuilt it. The same missing host made .toolbar(.hidden, for: .bottomBar) inert, which is why hiding the bar behind the picker had to be faked by removing every item — the workaround the old comment described.

Hosting the bar in a navigation stack fixes both, but it exposed a latent bug in the frame preference keys. The stack adds a subtree that is measured before layout and reports a frame with a real origin but no size, e.g. (148, 0, 0 x 0). The reducers guarded with next != .zero, which that rect clears, so it overwrote the live stock and waste frames and every card flight launched from the top of the screen instead of the pile. Guarding on size is what the check meant all along; the existing comment shows the same class of bug already occurred once on macOS, and the guard was simply too narrow to catch this variant.

Validation

  • xcodebuild ... -destination 'generic/platform=macOS' build succeeds.

  • xcodebuild ... -destination 'platform=macOS' test: 594 tests, 10 skipped, 0 failures.

  • iOS simulator build succeeds.

  • GameModePickerUITests.testTapOutsideDismissesGamePicker passes: the bar leaves while the picker is open and returns on dismiss, now through the supported visibility API.

  • Flight-planner inputs are unchanged with the stack in place, logged on both builds:

    before after
    stock (12, 114.667, 47 x 68.15) (12, 114.667, 47 x 68.15)
    waste (67, 114.667, 63.92 x 68.15) (67, 114.667, 63.92 x 68.15)
  • Screen recording of stock draws confirms cards fly from the stock pile to the waste, not from the top of the screen.

  • Toolbar flicker confirmed resolved on device.

UI Changes

  • The bottom toolbar no longer blanks and reappears when drawing from the stock.
  • No visual or layout change otherwise: the same items in the same order, and Auto Finish keeps its existing show/hide behavior.

contentview sits bare in the windowgroup, so bottombar items were
bridged onto the window root and board mutations tore them down — the
bar blanked and returned on every stock draw. it also left
`.toolbar(_:for: .bottomBar)` inert, so picker visibility was faked by
emptying the item list.

wrap the board in a navigation stack that only hosts, and drive picker
visibility through the real visibility api.

the stack adds a subtree measured before layout that reports a frame
with a real origin but no size, e.g. (148, 0, 0 x 0). the single-frame
preference keys rejected only `.zero`, so that candidate passed the
guard and clobbered the live stock and waste frames, sending every card
flight from the top of the screen. guard on size instead.
@cursor

cursor Bot commented Jul 20, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@austin-smith
austin-smith merged commit 939fffd into main Jul 20, 2026
3 checks passed
@austin-smith
austin-smith deleted the bottom-bar-navigation-host branch July 20, 2026 16:32
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