All skills
jamesrochabrun avatar

/apple-hig-designer

@c877664

Design iOS apps following Apple's Human Interface Guidelines. Generate native components, validate designs, and ensure accessibility compliance for iPhone, iPad, and Apple Watch.

Use this Skill: https://skilld.dev/gh/jamesrochabrun/skills/apple-hig-designer

This session only. Nothing lands on disk.

referencescomponents.md

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

iOS Components Catalog

Complete reference for native iOS UI components following Apple Human Interface Guidelines.

Navigation Components

Navigation Bar

Top bar for hierarchical navigation.

NavigationStack {
    List {
        Text("Item 1")
        Text("Item 2")
    }
    .navigationTitle("Title")
    .navigationBarTitleDisplayMode(.large) // or .inline
    .toolbar {
        ToolbarItem(placement: .navigationBarTrailing) {
            Button("Add") {
                // Action
            }
        }
    }
}

Guidelines:

  • Use .large for top-level views
  • Use .inline for detail views
  • Maximum 2-3 toolbar items
  • Keep actions relevant to context

Tab Bar

Bottom navigation for peer destinations.

TabView {
    HomeView()
        .tabItem {
            Label("Home", systemImage: "house")
        }

    SearchView()
        .tabItem {
            Label("Search", systemImage: "magnifyingglass")
        }
}

Guidelines:

  • 3-5 tabs maximum
  • Use SF Symbols for icons
  • One-word labels
  • Never hide or disable tabs

Toolbar

Actions for current context.

.toolbar {
    ToolbarItem(placement: .navigationBarTrailing) {
        Button("Edit") { }
    }

    ToolbarItem(placement: .bottomBar) {
        Button("Delete") { }
    }
}

Controls

Button

Primary action control.

// Prominent (primary action)
Button("Continue") { }
    .buttonStyle(.borderedProminent)

// Bordered (secondary action)
Button("Cancel") { }
    .buttonStyle(.bordered)

// Plain (tertiary action)
Button("Learn More") { }
    .buttonStyle(.plain)

Toggle (Switch)

Boolean control.

Toggle("Enable notifications", isOn: $isEnabled)
    .toggleStyle(.switch)

Slider

Continuous value selection.

Slider(value: $volume, in: 0...100)
    .accessibilityLabel("Volume")
    .accessibilityValue("\(Int(volume))%")

Picker

Selection from multiple options.

// Menu style
Picker("Size", selection: $size) {
    Text("Small").tag("S")
    Text("Medium").tag("M")
    Text("Large").tag("L")
}
.pickerStyle(.menu)

// Segmented (2-5 options)
Picker("View", selection: $viewType) {
    Text("List").tag(0)
    Text("Grid").tag(1)
}
.pickerStyle(.segmented)

TextField

Text input.

TextField("Username", text: $username)
    .textFieldStyle(.roundedBorder)
    .textContentType(.username)
    .textInputAutocapitalization(.never)
    .autocorrectionDisabled()

SecureField

Password input.

SecureField("Password", text: $password)
    .textFieldStyle(.roundedBorder)
    .textContentType(.password)

Content Views

List

Scrollable rows of content.

List {
    Section("Today") {
        ForEach(items) { item in
            NavigationLink {
                DetailView(item: item)
            } label: {
                HStack {
                    Image(systemName: item.icon)
                    Text(item.title)
                }
            }
        }
        .onDelete { indices in
            items.remove(atOffsets: indices)
        }
    }
}
.listStyle(.insetGrouped)

List Styles:

  • .plain - Edge-to-edge
  • .insetGrouped - Rounded sections (iOS default)
  • .sidebar - Navigation sidebar

ScrollView

Custom scrollable content.

ScrollView {
    VStack(spacing: 16) {
        ForEach(items) { item in
            CardView(item: item)
        }
    }
    .padding()
}

Grid

Multi-column layout.

// LazyVGrid for vertical scrolling
LazyVGrid(columns: [
    GridItem(.adaptive(minimum: 150))
]) {
    ForEach(items) { item in
        CardView(item: item)
    }
}

// LazyHGrid for horizontal scrolling
LazyHGrid(rows: [
    GridItem(.fixed(200))
]) {
    ForEach(items) { item in
        CardView(item: item)
    }
}

Presentations

Sheet (Modal)

Present content modally.

.sheet(isPresented: $showSheet) {
    NavigationStack {
        DetailView()
            .navigationTitle("Details")
            .toolbar {
                ToolbarItem(placement: .cancellationAction) {
                    Button("Cancel") {
                        showSheet = false
                    }
                }
            }
    }
    .presentationDetents([.medium, .large])
}

Detents:

  • .medium - Half screen
  • .large - Full screen
  • Custom: .height(400)

Alert

Important messages.

.alert("Delete Item?", isPresented: $showAlert) {
    Button("Delete", role: .destructive) {
        deleteItem()
    }
    Button("Cancel", role: .cancel) { }
} message: {
    Text("This action cannot be undone.")
}

Confirmation Dialog

Action selection.

.confirmationDialog("Options", isPresented: $showOptions) {
    Button("Edit") { }
    Button("Share") { }
    Button("Delete", role: .destructive) { }
    Button("Cancel", role: .cancel) { }
}

Indicators

Progress View

Loading indicator.

// Indeterminate
ProgressView()

// Determinate
ProgressView(value: progress, total: 1.0)

// With label
ProgressView("Loading...") {
    // Optional current task
    Text("5 of 10 items")
}

Activity Indicator

Spinning indicator.

ProgressView()
    .progressViewStyle(.circular)
    .scaleEffect(1.5)

Content Containers

Card View

Contained content block.

struct CardView: View {
    var body: some View {
        VStack(alignment: .leading, spacing: 12) {
            Text("Title")
                .font(.headline)

            Text("Description")
                .font(.subheadline)
                .foregroundColor(.secondary)

            Button("Action") { }
                .buttonStyle(.borderedProminent)
        }
        .padding()
        .background(Color(.systemBackground))
        .cornerRadius(12)
        .shadow(color: .black.opacity(0.1), radius: 8)
    }
}

GroupBox

Labeled group of views.

GroupBox("Settings") {
    Toggle("Notifications", isOn: $notifications)
    Toggle("Location", isOn: $location)
}

Form

Settings and input grouping.

Form {
    Section("Account") {
        TextField("Username", text: $username)
        SecureField("Password", text: $password)
    }

    Section("Preferences") {
        Toggle("Notifications", isOn: $notifications)
        Picker("Theme", selection: $theme) {
            Text("Light").tag("light")
            Text("Dark").tag("dark")
        }
    }
}

Best Practices

Navigation:

  • Use NavigationStack for hierarchical
  • Use TabView for flat (3-5 peers)
  • Never combine TabView + Toolbar in same view

Forms:

  • Group related inputs
  • Provide clear labels
  • Show validation errors inline
  • Use appropriate input types

Lists:

  • Use .insetGrouped style
  • Support swipe actions
  • Provide pull-to-refresh when relevant
  • Use sections for organization

Modals:

  • Use for focused tasks
  • Provide clear dismiss action
  • Don't nest modals
  • Use appropriate detent

For more details: https://developer.apple.com/design/human-interface-guidelines/components

Source: SKILL.md on GitHub

1 warning17d5 checks · Risk MEDIUM
  • Gen Agent Trust Hub17d

    The skill includes shell scripts for iOS component generation and validation that are vulnerable to command injection and data corruption. Specifically, the generation script uses 'eval' on user-supplied strings and performs unsafe 'sed' operations. Additionally, the skill processes external Swift code without sanitization, creating a surface for indirect prompt injection.

  • Socket17d

    No alerts

  • Snyk17d

    Risk: LOW · No issues

  • Runlayer7mo

    4/9 files flagged

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

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

Last checked against GitHub 2 months ago.

Dormantupdated 11 months ago

README badge

README badge for jamesrochabrun/skills/apple-hig-designer