swiftship/internal/skills/data/always-macos/layout/SKILL.md
macOS layout patterns: window sizing, toolbar, sidebar columns, resizable windows, Dynamic Type. Use when working on macOS layout, window management, or toolbar customization. Triggers: layout, window, toolbar, sidebar, defaultSize, windowResizability.
npx skillsauth add abdullah4ai/apple-dev-docs 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.
WindowGroup {
ContentView()
}
.defaultSize(width: 900, height: 600)
// Allow free resizing with a minimum content size
WindowGroup {
ContentView()
.frame(minWidth: 600, minHeight: 400)
}
.windowResizability(.contentMinSize)
// Fixed content size (non-resizable)
Window("Preferences", id: "prefs") {
PreferencesView()
}
.windowResizability(.contentSize)
NavigationSplitView {
SidebarView()
} detail: {
DetailView()
.toolbar {
ToolbarItem(placement: .principal) {
Text("Document")
.font(AppTheme.Fonts.headline)
}
ToolbarItemGroup {
Button("Share", systemImage: "square.and.arrow.up") { share() }
Button("Settings", systemImage: "gear") { openSettings() }
}
}
}
.toolbar(id: "editor") {
ToolbarItem(id: "bold", placement: .automatic) {
Button("Bold", systemImage: "bold") { toggleBold() }
}
ToolbarItem(id: "italic", placement: .automatic) {
Button("Italic", systemImage: "italic") { toggleItalic() }
}
}
.toolbarRole(.editor)
NavigationSplitView {
SidebarView()
.navigationSplitViewColumnWidth(min: 180, ideal: 220, max: 300)
} content: {
ContentList()
.navigationSplitViewColumnWidth(min: 250, ideal: 300)
} detail: {
DetailView()
}
GeometryReader { geometry in
let columns = geometry.size.width > 800
? [GridItem(.adaptive(minimum: 200))]
: [GridItem(.adaptive(minimum: 150))]
LazyVGrid(columns: columns) {
ForEach(items) { item in
ItemCard(item: item)
}
}
}
@Environment(\.dynamicTypeSize) var dynamicTypeSize
var body: some View {
VStack(spacing: AppTheme.Spacing.medium) {
Text(title)
.font(AppTheme.Fonts.headline)
Text(subtitle)
.font(AppTheme.Fonts.body)
}
.padding(AppTheme.Spacing.large)
}
macOS windows have title bar inset and traffic light buttons area:
VStack {
content
}
.padding() // Respect default window padding
.fileImporter(
isPresented: $showImporter,
allowedContentTypes: [.json, .plainText]
) { result in
handleImport(result)
}
.fileExporter(
isPresented: $showExporter,
document: myDocument,
contentType: .json
) { result in
handleExport(result)
}
.edgesIgnoringSafeArea patterns for notch/Dynamic IslandUIScreen.main.bounds — use GeometryReader or window sizing.defaultSize(width:height:) for initial window dimensions.windowResizability(.contentMinSize) for resizable windows with minimums.toolbar {} with placement for toolbar items.toolbarRole(.editor) for user-customizable toolbars.navigationSplitViewColumnWidth() to control sidebar widths.fileImporter() / .fileExporter() for open/save panelstesting
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.