Swiftui Expert Skill

Expert SwiftUI automation skill for building polished iOS and macOS app interfaces

SwiftUI Expert Skill is a community skill for building production-quality SwiftUI applications, covering view composition, state management, navigation patterns, custom layouts, animations, and performance optimization for declarative UI development.

What Is This?

Overview

SwiftUI Expert Skill provides advanced patterns for building SwiftUI interfaces. It covers view composition with extracted subviews, view modifiers, and preference keys for clean hierarchies, state management using @State, @Binding, @Observable, and @Environment for reactive data flow, navigation with NavigationStack, NavigationSplitView, and programmatic routing for multi-platform apps, custom layouts with the Layout protocol for precise view positioning, and animations with matched geometry effects, phase animators, and keyframe animations. The skill enables developers to build polished, performant SwiftUI applications that follow Apple platform conventions.

Who Should Use This

This skill serves iOS and macOS developers building production applications with SwiftUI, teams adopting SwiftUI for new features in existing UIKit applications, and engineers designing reusable SwiftUI components and design systems.

Why Use It?

Problems It Solves

Large SwiftUI views become unreadable without proper decomposition into subviews and modifiers. State management confusion between @State, @StateObject, and @Observable leads to unexpected UI behavior. Navigation patterns changed significantly across SwiftUI versions causing migration challenges. Performance issues from unnecessary view redraws are difficult to diagnose without understanding the rendering pipeline.

Core Highlights

View decomposition keeps body properties small and focused on layout. @Observable macro simplifies state management with automatic dependency tracking. NavigationStack provides type-safe programmatic navigation with path binding. Layout protocol enables custom positioning logic beyond built-in stacks and grids.

How to Use It?

Basic Usage

import SwiftUI
import Observation

@Observable
class TaskStore {
    var tasks: [TaskItem] = []
    var filter: Filter = .all

    var filteredTasks:
        [TaskItem] {
        switch filter {
        case .all:
            return tasks
        case .active:
            return tasks.filter {
                !$0.isDone }
        case .completed:
            return tasks.filter {
                $0.isDone }
        }
    }

    enum Filter: String,
        CaseIterable {
        case all, active,
            completed
    }
}

struct TaskListView: View {
    @State private var store
        = TaskStore()

    var body: some View {
        NavigationStack {
            List(store
                .filteredTasks) {
                task in
                TaskRow(task: task)
            }
            .toolbar {
                Picker("Filter",
                    selection:
                        $store
                            .filter
                ) {
                    ForEach(
                        TaskStore
                            .Filter
                            .allCases,
                        id: \.self
                    ) { f in
                        Text(
                            f.rawValue
                                .capitalized)
                    }
                }
            }
            .navigationTitle(
                "Tasks")
        }
    }
}

Real-World Examples

import SwiftUI

// Custom layout
struct FlowLayout: Layout {
    var spacing: CGFloat = 8

    func sizeThatFits(
        proposal:
            ProposedViewSize,
        subviews: Subviews,
        cache: inout ()
    ) -> CGSize {
        let result = arrange(
            proposal: proposal,
            subviews: subviews)
        return result.size
    }

    func placeSubviews(
        in bounds: CGRect,
        proposal:
            ProposedViewSize,
        subviews: Subviews,
        cache: inout ()
    ) {
        let result = arrange(
            proposal: proposal,
            subviews: subviews)
        for (index, offset)
            in result.offsets
                .enumerated() {
            subviews[index].place(
                at: CGPoint(
                    x: bounds.minX
                        + offset.x,
                    y: bounds.minY
                        + offset.y),
                proposal:
                    .unspecified)
        }
    }

    private func arrange(
        proposal:
            ProposedViewSize,
        subviews: Subviews
    ) -> (size: CGSize,
          offsets: [CGPoint]) {
        let width = proposal
            .width ?? .infinity
        var offsets: [CGPoint]
            = []
        var x: CGFloat = 0
        var y: CGFloat = 0
        var rowH: CGFloat = 0

        for sub in subviews {
            let size = sub
                .sizeThatFits(
                    .unspecified)
            if x + size.width
                > width && x > 0 {
                x = 0
                y += rowH + spacing
                rowH = 0
            }
            offsets.append(
                CGPoint(
                    x: x, y: y))
            rowH = max(
                rowH, size.height)
            x += size.width
                + spacing
        }

        return (
            CGSize(width: width,
                height: y + rowH),
            offsets)
    }
}

Advanced Tips

Use EquatableView or custom Equatable conformance to prevent unnecessary redraws for views with expensive body computations. Leverage @Environment for dependency injection of services and configuration throughout the view hierarchy. Use matchedGeometryEffect for smooth hero transitions between navigation states.

When to Use It?

Use Cases

Build a multi-platform app with NavigationSplitView that adapts between iPhone, iPad, and Mac layouts. Create a tag cloud component using custom FlowLayout for dynamic content wrapping. Implement a settings screen with @Observable state management and environment injection.

Related Topics

SwiftUI views, @Observable, NavigationStack, Layout protocol, and SwiftUI animations.

Important Notes

Requirements

iOS 17 or later for @Observable macro support. Xcode 15 or later for SwiftUI development. SwiftUI knowledge including view lifecycle and data flow concepts.

Usage Recommendations

Do: extract subviews when body properties exceed twenty lines for readability. Use @Observable over @StateObject for new projects targeting iOS 17 and later. Prefer value types in view state to minimize reference counting overhead.

Don't: put heavy computation directly in view body properties which recompute on every state change. Use @EnvironmentObject when @Environment with @Observable provides a simpler alternative. Nest NavigationStacks which causes unexpected navigation behavior.

Limitations

@Observable requires iOS 17 limiting adoption for apps supporting older versions. Custom Layout protocol is available from iOS 16 and does not cover all positioning scenarios. SwiftUI previews can be slow with complex view hierarchies and external dependencies.