Skip to content

Settings: Sex picker → .menu, fixes oversized Settings screen (#43)#72

Merged
ryanbr merged 1 commit into
mainfrom
fix-settings-sex-picker-overflow
Jul 8, 2026
Merged

Settings: Sex picker → .menu, fixes oversized Settings screen (#43)#72
ryanbr merged 1 commit into
mainfrom
fix-settings-sex-picker-overflow

Conversation

@ryanbr

@ryanbr ryanbr commented Jul 8, 2026

Copy link
Copy Markdown
Owner

Fixes #43 — the Settings screen renders oversized / off the right edge on iOS. Two reporters (japothek; adrnxq — German, since ~8.3.3), Settings-only, every other screen fine.

Cause

The Sex row (SettingsView.swift) is a .pickerStyle(.segmented) picker (Male / Female / Non-binary) with a bare .fixedSize(). FormRow lays out Text(label).frame(maxWidth: .infinity) + control in an HStack — so a segmented picker there collapses without .fixedSize(), but with it the picker is forced to its full intrinsic width. Three labels (one long, longer still in German "Nicht-binär") or an enlarged Text Size make that width exceed the screen, pushing the whole Settings column past the edge. That single overflowing row is why the entire screen looks oversized while other screens are fine. It's the only bare .fixedSize() in the file (the rest are horizontal: false, which is safe). Blame shows the code predates 8.2.2, so the trigger was the German localization lengthening the labels.

Fix (minimal)

Switch that one picker to .pickerStyle(.menu) and drop .fixedSize(). A menu is a compact "Male ▾" button that fits any label length, needs no fixed sizing, and is immune to Dynamic Type / localization. Tinted to match the app's other menu pickers (e.g. the backup keep-count). No other rows touched.

Testing

SwiftUI can't build on the maintainer's box (WSL); this is a standard modifier swap using an existing palette token already used 40× in the file. Verified by inspection + the layout reasoning above; a testing build / on-device check confirms the visual.

File: Strand/Screens/SettingsView.swift.

…oversized Settings screen (#43)

In FormRow's label(maxWidth:.infinity) + control HStack, a segmented picker
collapses without .fixedSize() but is forced to its full intrinsic width WITH it.
With three labels — one long ("Non-binary", longer in German "Nicht-binär") — or
an enlarged Text Size, that intrinsic width pushes the whole Settings column past
the screen edge, so the entire screen reads as oversized/off-screen while every
other screen is fine. iOS-specific and localization-sensitive; matches both
reporters (one German, since the ~8.3.3 localization landing).

A .menu picker is a compact button that fits any label length, needs no
.fixedSize(), and is immune to Dynamic Type / localization. Tinted to match the
app's other menu pickers.
@ryanbr ryanbr merged commit 85587c4 into main Jul 8, 2026
tanarchytan pushed a commit to tanarchytan/noop that referenced this pull request Jul 8, 2026
…le-RTC "missed sleep" (ryanbr#67)

A reset/stale strap RTC banks last night's sleep with a years-old timestamp, so
the offload files it far in the past — off the recent timeline, where it reads as
"missed sleep". The log showed the strap was stale and that rows persisted, but
NOT where those rows landed or what clock reference decoded them, so the misdating
was invisible.

Logging only — no BLE/offload behaviour change:

- Backfiller: new "Backfill: rows landed on <date(s)>" session line, plus the
  effective clock state — "IDENTITY fallback (GET_CLOCK never correlated) -
  stale-record correction OFF", "strap clock Nd behind wall - correction engaged",
  or "clock ref in sync". The dates are the ACTUAL post-correction landing days
  (the same night-keys the persist tally builds), so a night that landed in 2024
  is self-evident. Captures the decode ref on the first chunk; reset in begin().

- DebugDataDiagnostics: the existing "Strap clock: Nd behind wall" line now notes
  recent sleep may be filed ~Nd in the past (ryanbr#67), not just that the alarm is
  unreliable.

- Tests: cover the new formatter — identity-fallback past-date signature,
  correlated-stale "correction engaged", in-sync, multi-night UTC range, and the
  no-em-dash convention shared with the sibling strap-log lines.

Pairs with the root-cause investigation on ryanbr#67: on a reset-RTC strap the offload
falls back to an identity clock ref (Backfiller.swift), which zeroes the offset
FIX ryanbr#72's correctedWall needs, so stale records are stored verbatim. This makes
that failure mode visible before touching the BLE clock handshake.
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.

Oversized settings UI

1 participant