swiftui-interaction-footgunslisted
Install: claude install-skill wei18/apple-dev-skills
# SwiftUI Interaction Footguns
A class of bugs that look fine in code but break at runtime. These have shipped to production from real projects (see Sightings section). Sweep this checklist on every SwiftUI View review.
## When to invoke
- Reviewing any new or modified SwiftUI View
- Reviewing `Button` / `NavigationLink` / `TabView` / `Form` / `Menu`
- Reviewing Mac variants (`NavigationSplitView` / sidebar)
- After a macOS or iPad smoke test surfaces a tap or navigation bug
- Before declaring a Phase complete that ships new View code
## Checklist
### Tap target & hit-test
- `Button { } label: { LayoutWithSpacer }` `.buttonStyle(.plain)` → hit-test shrinks to drawn content; the Spacer-expanded area is **not** tappable. **Fix:** `.contentShape(Rectangle())` on the label's outermost container.
- Same trap for `NavigationLink`, `Menu`, and any custom interactive view with `.onTapGesture` + Spacer / `frame(maxWidth: .infinity)` / padding.
- Padding and `frame(maxWidth: .infinity)` enlarge the visual frame but do **not** automatically enlarge the hit region under `.plain`. When in doubt, add `.contentShape`.
### Accessibility identifiers (XCUITest anchors)
- An `.accessibilityIdentifier` on a **container** can cascade down and clobber its accessibility-element descendants' own identifiers — in XCUITest the children then report the container's id, and a query for the child's id finds nothing ("No matches found"). **Fix:** put the container-level id on a leaf (a title `Text`