swiftship/internal/skills/data/always-watchos/layout/SKILL.md
watchOS layout: glanceable design, watch-sized stacks, containerRelativeFrame, 1-2 second interaction principles. Use when working on shared watchOS patterns related to layout.
npx skillsauth add abdullah4ai/apple-developer-toolkit layoutInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Glanceable design: users interact with Apple Watch for 1-2 seconds. Every view must communicate its purpose instantly.
// Good - simple vertical stack, fills naturally
VStack(spacing: 8) {
Text("Heart Rate")
.font(AppTheme.Fonts.caption2)
.foregroundStyle(.secondary)
Text("72")
.font(AppTheme.Fonts.largeTitle)
Text("BPM")
.font(AppTheme.Fonts.caption)
.foregroundStyle(.secondary)
}
// Good - buttons fill width on watch
Button("Start Workout") {
startWorkout()
}
.buttonStyle(.borderedProminent)
// Buttons naturally fill width on watchOS — no .frame(maxWidth:) needed
Image("chart")
.resizable()
.containerRelativeFrame(.horizontal) { width, _ in
width * 0.9
}
.aspectRatio(contentMode: .fit)
// Good - same view, different states
SomeView()
.opacity(isVisible ? 1 : 0)
// Avoid - creates/destroys view identity
if isVisible {
SomeView()
}
// Good - separate struct, SwiftUI can skip body when inputs unchanged
struct MetricDisplay: View {
let value: Int
let unit: String
var body: some View {
VStack {
Text("\(value)")
.font(AppTheme.Fonts.title2)
Text(unit)
.font(AppTheme.Fonts.caption2)
.foregroundStyle(.secondary)
}
}
}
GeometryReader — use containerRelativeFrame or let stacks fill naturallyUIScreen.main.bounds — doesn't exist on watchOSNavigationSplitView — watch is single-column onlyVStack or single-column List.frame(maxWidth: 700) readability constraints — the screen is already smallAnyLayout switching — there's only one layout direction on watchList for scrollable content, ScrollView for custom layouts.title, .largeTitle) for primary information.caption, .caption2) for labels and secondary info@ScaledMetric for custom dimensions that respect Dynamic Typetesting
Use for 3D games: racing, 3D sports, board games, marble maze, tower defense, bowling. SceneKit + SceneView architecture, 3D scene hierarchy, physics, game loop, primitives, materials, cameras, particles, audio.
documentation
Game UI patterns: SwiftUI HUD overlays on SpriteKit, menus (main/pause/game-over), virtual joystick/d-pad, score displays, health bars, tutorial onboarding.
tools
Download free game sprites/textures/3D models and generate procedural assets. Covers nw_download_asset tool, texture factories, sprite atlas organization, 3D model loading, and programmatic asset creation.
testing
Use for 2D games: arcade, puzzle, sports, ping pong, platformer, shooter, 2D racing. SpriteKit + SpriteView architecture, scene hierarchy, physics, game loop, audio, particles, game feel.