How to Create a Form in SwiftUI

Use a Form in SwiftUI when your app needs structured user input with native grouped styling, such as settings, profile editing, checkout details, or account preferences.

What you’ll build or solve

You’ll learn how to create a Form in SwiftUI with text fields, toggles, sections, and bound state. You’ll also know when VStack is a better fit.

When this approach works best

This approach is the right choice when the UI should feel like a native iOS settings or input screen.

Common real-world scenarios include:

  • Profile forms
  • Settings pages
  • Checkout details
  • Feedback forms
  • Account preferences

This is a bad idea when the layout needs fully custom visual design beyond standard form styling.

Prerequisites

You only need:

  • Basic SwiftUI views
  • @State
  • Familiarity with bindings

Step-by-step instructions

Step 1: Create a basic Form

A form groups inputs with native styling.

import SwiftUI

struct ProfileForm: View {
    @State private var name = ""

    var body: some View {
        Form {
            TextField("Your name", text: $name)
        }
    }
}

This automatically creates a grouped native form.

Step 2: Add multiple field types

Real forms combine multiple controls.

struct SettingsForm: View {
    @State private var email = ""
    @State private var notificationsEnabled = true

    var body: some View {
        Form {
            TextField("Email", text: $email)

            Toggle("Notifications", isOn: $notificationsEnabled)
        }
    }
}

This keeps every field bound to state.

Step 3: Organize fields with Section

Sections improve readability.

Form {
    Section("Account") {
        TextField("Email", text: $email)
    }

    Section("Preferences") {
        Toggle("Notifications", isOn: $notificationsEnabled)
    }
}

This creates clear grouped areas.

What to look for:

  • Form gives native grouped styling
  • Use @State for field values
  • Bind inputs with $
  • Section improves structure
  • Great for settings-like screens

Examples you can copy

Simple text field

Form {
    TextField("Name", text: $name)
}

Toggle form

Toggle("Dark Mode", isOn: $isDarkMode)

Sectioned profile form

Section("Profile") {

Common mistakes and how to fix them

Mistake 1: Forgetting bindings

What the reader might do:

TextField("Name", text: name)

Why it breaks: SwiftUI inputs need bindings.

Corrected approach:

Use $name.

Mistake 2: Using Form for custom layouts

What the reader might do:

Try to create dashboard cards inside a form.

Why it breaks: form styling is intentionally opinionated.

Corrected approach:

Use VStack, List, or ScrollView.

Mistake 3: Overloading one section

What the reader might do:

Put 15 unrelated fields in one block.

Why it breaks: usability drops.

Corrected approach:

Group related fields with Section.

Troubleshooting

If the input does not update, check the $ binding.

If the layout feels too rigid, switch to VStack.

If the form gets long, add sections.

If state changes do not persist, lift the binding to a parent view model.

Quick recap

  • Use Form for native grouped input UIs
  • Store field values in @State
  • Pass bindings with $
  • Use Section for structure
  • Switch to VStack for custom layouts