All skills
avdlee avatar

/swiftui-expert-skill

@1e522cf

Use when writing, reviewing, or refactoring SwiftUI code for iOS or macOS, including state and `@Observable` data flow, view composition, resizable layouts, safe areas, display scale, performance, lists, environment, localization, animation, Liquid Glass, and API migration. Also use for iPhone Duo, foldable, or large-display layouts (`NavigationSplitView` on large displays, two-column reflow, foldable grids, `ArrangementView`, `ReservedRegion`), hinge effects, vertical bars, `@State` initialization or synthesized-property diagnostics, `@ContentBuilder` ambiguity, `reorderable` drag/drop, custom `AsyncImage` `URLSession`, swipe actions outside List, item-bound `alert`/`confirmationDialog`, `ToolbarOverflowMenu`, `AnimatableValues`, Document APIs (`Document`/`DocumentReader`), and Instruments `.trace` capture or analysis.

Use this Skill: https://skilld.dev/gh/avdlee/swiftui-agent-skill/swiftui-expert-skill

This session only. Nothing lands on disk.

referencesmacos-window-styling.md

≈2.2k tokens on demand. Your agent reads this file only when SKILL.md points to it.

macOS Window & Toolbar Styling Reference

Window configuration, toolbar styles, sizing, positioning, and navigation patterns specific to macOS SwiftUI apps.

Table of Contents


Quick Lookup Table

API Availability macOS-Only? Usage
windowToolbarStyle(_:) macOS 11.0+ Yes Sets toolbar style: .unified, .unifiedCompact, .expanded
windowStyle(_:) macOS 11.0+ No Supports .hiddenTitleBar for chromeless windows
windowResizability(_:) macOS 13.0+ No Controls resize handle and green zoom button behavior
defaultSize(width:height:) macOS 13.0+ No Initial frame size when user creates a new window
defaultPosition(_:) macOS 13.0+ No Initial window position on screen
windowIdealPlacement(_:) macOS 15.0+ No Closure with display geometry for precise window positioning
menuBarExtraStyle(_:) macOS 13.0+ Yes Sets MenuBarExtra to .menu or .window style
NavigationSplitView macOS 13.0+ No Columns always visible side-by-side on macOS; translucent sidebar
Inspector macOS 14.0+ No Trailing-edge sidebar panel; resizable by dragging

Toolbar Styles

windowToolbarStyle (macOS-only)

Controls how the toolbar and title bar are displayed. Applied to a scene.

@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
        // Title bar and toolbar in a single row
        .windowToolbarStyle(.unified)
    }
}

Available styles:

Style Description
.automatic System default
.unified Title bar and toolbar in a single combined row
.unifiedCompact Same as unified but with reduced vertical height
.expanded Title bar displayed above the toolbar (more toolbar space)
// Unified compact — minimal chrome
.windowToolbarStyle(.unifiedCompact)

// Expanded — title bar above toolbar
.windowToolbarStyle(.expanded)

// Unified with title hidden
.windowToolbarStyle(.unified(showsTitle: false))

Toolbar content

struct ContentView: View {
    @State private var searchText = ""

    var body: some View {
        NavigationSplitView {
            SidebarView()
        } detail: {
            DetailView()
        }
        .toolbar {
            ToolbarItem(placement: .automatic) {
                Button(action: addItem) {
                    Label("Add", systemImage: "plus")
                }
            }
        }
        .searchable(text: $searchText, placement: .sidebar)
    }
}

Window Style

windowStyle

Set the visual style of a window. Use .hiddenTitleBar for chromeless, immersive windows.

// Standard title bar (default)
WindowGroup {
    ContentView()
}
.windowStyle(.titleBar)

// Hidden title bar — chromeless window
WindowGroup {
    ContentView()
}
.windowStyle(.hiddenTitleBar)

Use case: .hiddenTitleBar is useful for media players, custom-chrome apps, or immersive experiences where the standard title bar is unwanted.


Window Sizing

windowResizability, defaultSize, defaultPosition

These modifiers work together to configure window sizing and placement:

WindowGroup {
    ContentView()
        .frame(minWidth: 600, minHeight: 400)
}
.defaultSize(width: 900, height: 600)
.defaultPosition(.center)
.windowResizability(.contentMinSize)

windowResizability options:

Value Behavior
.automatic System decides resize behavior
.contentSize Fixed to content size; no user resize; zoom button disabled
.contentMinSize Resizable with minimum based on content's minWidth/minHeight

defaultPosition options: .center, .topLeading, .top, .topTrailing, .leading, .trailing, .bottomLeading, .bottom, .bottomTrailing

Guidelines:

  • Set minWidth/minHeight via .frame() on content, enforce with .contentMinSize
  • Use .defaultSize() for initial dimensions (larger than minimums)
  • defaultSize also accepts CGSize

windowIdealPlacement (macOS 15.0+)

For precise programmatic positioning, use a closure with display geometry:

.windowIdealPlacement { context in
    let screen = context.defaultDisplay.visibleArea
    return WindowPlacement(x: screen.midX, y: screen.midY,
                           width: screen.width / 2, height: screen.height)
}

MenuBarExtra Style (macOS-only)

Choose between dropdown menu and popover panel for MenuBarExtra.

// Dropdown menu (default)
MenuBarExtra("Status", systemImage: "chart.bar") {
    Button("Action") { /* ... */ }
}
.menuBarExtraStyle(.menu)

// Popover panel with custom SwiftUI content
MenuBarExtra("Status", systemImage: "chart.bar") {
    DashboardView()
}
.menuBarExtraStyle(.window)

Navigation Layout (macOS behavior)

NavigationSplitView

On macOS, NavigationSplitView displays columns side-by-side (never overlaid). The sidebar gets a translucent material background. Columns support variable-width resizing by the user.

NavigationSplitView {
    List(items, selection: $selectedId) { item in
        Text(item.name)
    }
    .navigationSplitViewColumnWidth(min: 180, ideal: 220, max: 300)
} detail: {
    DetailView(id: selectedId)
}
.navigationSplitViewStyle(.balanced)

Use the three-column variant (sidebar / content / detail) for master-detail-detail layouts. Customize column widths with .navigationSplitViewColumnWidth(min:ideal:max:).

Inspector (macOS 14.0+)

A trailing-edge panel for supplementary information. On macOS, it appears as a sidebar-style panel that can be resized by dragging its edge.

struct ContentView: View {
    @State private var showInspector = false

    var body: some View {
        MainContent()
            .inspector(isPresented: $showInspector) {
                InspectorView()
                    .inspectorColumnWidth(min: 200, ideal: 250, max: 400)
            }
            .toolbar {
                ToolbarItem {
                    Button {
                        showInspector.toggle()
                    } label: {
                        Label("Inspector", systemImage: "info.circle")
                    }
                }
            }
    }
}

Commands & Keyboard

Commands, CommandGroup, CommandMenu

Define menu bar commands. On macOS, these populate the menu bar directly. On iOS, they create key commands.

.commands {
    CommandMenu("Tools") {
        Button("Run Analysis") { /* ... */ }
            .keyboardShortcut("r", modifiers: [.command, .shift])
    }
    CommandGroup(after: .newItem) {
        Button("New From Template...") { /* ... */ }
    }
}

CommandGroup placement options: .replacing(_:) replaces a system group, .before(_:) / .after(_:) inserts adjacent to it. Common placements: .newItem, .saveItem, .help, .toolbar, .sidebar.

KeyboardShortcut

On macOS, shortcuts are displayed alongside menu items and in button tooltips on hover.

Button("Save") {
    save()
}
.keyboardShortcut("s", modifiers: .command)

Button("Delete") {
    delete()
}
.keyboardShortcut(.delete, modifiers: .command)

openWindow

Programmatically open a window. If the target window is already open, brings it to the front.

struct ToolbarActions: View {
    @Environment(\.openWindow) private var openWindow

    var body: some View {
        Button("Connection Doctor") {
            openWindow(id: "connection-doctor")
        }

        Button("Show Message") {
            openWindow(value: message.id)  // Type-matched to WindowGroup
        }
    }
}

Best Practices

  • Use .unified or .unifiedCompact for most apps — .expanded only when you need many toolbar items
  • Set min frame sizes on content and use .windowResizability(.contentMinSize) to enforce them
  • Always provide defaultSize so new windows start at a reasonable size
  • Use NavigationSplitView for sidebar navigation — not HSplitView
  • Use Inspector for supplementary panels — it integrates with the toolbar automatically
  • Define Commands for all repeatable actions — users expect keyboard shortcuts on macOS
  • Use #if os(macOS) to wrap macOS-only window configuration in multiplatform projects

Source: SKILL.md on GitHub

No alerts2d5 checks · Risk SAFE
  • Gen Agent Trust Hub2d

    The skill is a professional-grade assistant for SwiftUI development and performance profiling. It includes Python scripts to interface with the Xcode xctrace CLI for recording and analyzing Instruments traces. All identified code and instructions are consistent with its stated purpose and follow security best practices.

  • Socket2d

    No alerts

  • Snyk2d

    Risk: LOW · No issues

  • Runlayer6mo

    19 files scanned · No issues

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at 1e522cf. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub yesterday.

Activeupdated 3 days ago
  • Performance
  • swiftui
  • ios
  • macos
  • instruments
  • state-management
  • view-composition
  • accessibility
  • animations

README badge

README badge for avdlee/swiftui-agent-skill/swiftui-expert-skill

Provides guidance for writing, reviewing, and refactoring SwiftUI code for iOS and macOS, including state management, view composition, performance optimization, and Instruments trace recording and analysis. Covers deprecated API detection, animation patterns, accessibility, and Liquid Glass adoption.

Generated from the current SKILL.md.

Does this skill work with both iOS and macOS?
Yes. The skill covers SwiftUI for both iOS and macOS, with dedicated reference sections for macOS-specific patterns like scenes, window styling, and views (HSplitView, Table, PasteButton).
Can this skill help me record and analyze Instruments traces?
Yes. The skill includes workflows to record traces via `record_trace.py` (with template selection for real devices vs simulators) and analyze them via `analyze_trace.py` to identify hangs, hitches, CPU hotspots, and excessive view updates.
Does this skill enforce a specific architecture pattern?
No. It focuses on correctness and performance without mandating MVVM, VIPER, or other architectural styles, though it encourages separating business logic from views for testability.
What does the skill do about deprecated APIs?
It consults `references/latest-apis.md` at the start of every task to identify and replace deprecated APIs with modern equivalents across iOS 15+ through iOS 26+, and gates version-specific APIs with `#available`.
Does this skill handle Liquid Glass effects?
Yes, but only when explicitly requested by the user. It includes guidance in `references/liquid-glass.md` for iOS 26+ Liquid Glass adoption with sensible fallbacks for earlier versions.

Generated from the current SKILL.md. These answers refresh after source changes.