smithery/rektoooooo

swiftui-layout

SwiftUI layout and container expert for arranging views. Use when working with VStack, HStack, ZStack, Grid, LazyVGrid, LazyHGrid, GeometryReader, spacing, padding, alignment, frames, safe areas, or responsive layouts.

Installation

$ npx skills add smithery/rektoooooo --skill swiftui-layout

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from smithery/rektoooooo · top by installs.

npx skills add smithery/rektoooooo

Browse all from smithery/rektoooooo

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 6,221 B
  • docs SUMMARY.md 240 B

History

  1. First recorded snapshot · 0 installs

SKILL.md

SwiftUI Layout

Expert guidance for arranging and positioning views in SwiftUI.

Stack Containers

VStack (Vertical)

VStack(alignment: .leading, spacing: 16) {
    Text("Title")
        .font(.headline)
    Text("Subtitle")
        .font(.subheadline)
    Text("Body text")
}

HStack (Horizontal)

HStack(alignment: .center, spacing: 12) {
    Image(systemName: "star")
    Text("Favorite")
    Spacer()
    Text("5")
}

ZStack (Overlay)

ZStack(alignment: .bottomTrailing) {
    Image("background")
        .resizable()
        .aspectRatio(contentMode: .fill)

    Text("Overlay")
        .padding()
        .background(.black.opacity(0.7))
        .foregroundStyle(.white)
}

Lazy Containers

LazyVStack & LazyHStack

// Only loads visible items - use for long lists
ScrollView {
    LazyVStack(spacing: 8) {
        ForEach(items) { item in
            ItemRow(item: item)
        }
    }
    .padding()
}

LazyVGrid

let columns = [
    GridItem(.flexible()),
    GridItem(.flexible()),
    GridItem(.flexible())
]

ScrollView {
    LazyVGrid(columns: columns, spacing: 16) {
        ForEach(items) { item in
            ItemCard(item: item)
        }
    }
    .padding()
}

Adaptive Grid

let columns = [
    GridItem(.adaptive(minimum: 100, maximum: 200))
]

LazyVGrid(columns: columns) {
    ForEach(items) { item in
        ItemCard(item: item)
    }
}

GeometryReader

Reading Size

GeometryReader { geometry in
    VStack {
        Text("Width: \(geometry.size.width)")
        Text("Height: \(geometry.size.height)")

        Rectangle()
            .fill(.blue)
            .frame(width: geometry.size.width * 0.5)
    }
}

Safe Area

GeometryReader { geometry in
    VStack {
        Text("Safe Area Top: \(geometry.safeAreaInsets.top)")
        Text("Safe Area Bottom: \(geometry.safeAreaInsets.bottom)")
    }
}

Spacing & Padding

Padding

Text("Padded")
    .padding()                    // All sides, default amount
    .padding(.horizontal, 20)     // Horizontal only
    .padding(.vertical, 10)       // Vertical only
    .padding(.top, 30)            // Single edge
    .padding(EdgeInsets(top: 10, leading: 20, bottom: 10, trailing: 20))

Spacer

HStack {
    Text("Left")
    Spacer()           // Pushes items apart
    Text("Right")
}

HStack {
    Text("Left")
    Spacer(minLength: 20)  // Minimum spacing
    Text("Right")
}

Divider

VStack {
    Text("Above")
    Divider()
        .background(.gray)
    Text("Below")
}

Frame & Sizing

Fixed Frame

Text("Fixed Size")
    .frame(width: 200, height: 100)
    .background(.blue)

Flexible Frame

Text("Flexible")
    .frame(maxWidth: .infinity)              // Full width
    .frame(minHeight: 100, maxHeight: 300)   // Height range
    .frame(idealWidth: 200)                  // Preferred size

Aspect Ratio

Image("photo")
    .resizable()
    .aspectRatio(16/9, contentMode: .fit)

Rectangle()
    .aspectRatio(1, contentMode: .fit)  // Square

Alignment

Stack Alignment

VStack(alignment: .leading) {    // .leading, .center, .trailing
    Text("Short")
    Text("Medium length")
    Text("Very long text here")
}

HStack(alignment: .top) {        // .top, .center, .bottom, .firstTextBaseline
    Text("Tall\nText")
    Text("Short")
}

Frame Alignment

Text("Aligned")
    .frame(maxWidth: .infinity, alignment: .leading)

Custom Alignment

extension VerticalAlignment {
    struct CustomAlignment: AlignmentID {
        static func defaultValue(in context: ViewDimensions) -> CGFloat {
            context[.top]
        }
    }
    static let custom = VerticalAlignment(CustomAlignment.self)
}

ScrollView

Basic ScrollView

ScrollView {
    VStack(spacing: 20) {
        ForEach(items) { item in
            ItemRow(item: item)
        }
    }
    .padding()
}

Horizontal ScrollView

ScrollView(.horizontal, showsIndicators: false) {
    HStack(spacing: 16) {
        ForEach(items) { item in
            ItemCard(item: item)
        }
    }
    .padding()
}

ScrollViewReader

ScrollViewReader { proxy in
    ScrollView {
        ForEach(items) { item in
            ItemRow(item: item)
                .id(item.id)
        }
    }
    .onChange(of: selectedItem) { _, newItem in
        withAnimation {
            proxy.scrollTo(newItem.id, anchor: .center)
        }
    }
}

Safe Areas

Ignoring Safe Area

Color.blue
    .ignoresSafeArea()              // All edges
    .ignoresSafeArea(.top)          // Top only
    .ignoresSafeArea(.keyboard)     // Keyboard only

Safe Area Inset

List(items) { item in
    Text(item.name)
}
.safeAreaInset(edge: .bottom) {
    Button("Add Item") { }
        .padding()
        .background(.ultraThinMaterial)
}

Responsive Layout

ViewThatFits

ViewThatFits {
    HStack {
        Image(systemName: "star")
        Text("Favorites")
        Text("View all your favorite items")
    }

    VStack {
        Image(systemName: "star")
        Text("Favorites")
    }
}

Size Classes

@Environment(\.horizontalSizeClass) var horizontalSizeClass

var body: some View {
    if horizontalSizeClass == .compact {
        VStack { content }
    } else {
        HStack { content }
    }
}

Apple Documentation