← All courses

Forms & User Input

🗓 May 31, 2026 ⏱ 2 min read

The Form container

SwiftUI’s Form automatically gives inputs the native, grouped settings-screen look. You just place controls inside it and SwiftUI styles them correctly per platform.

struct SettingsView: View {
    @State private var name = ""
    @State private var notifications = true
    @State private var volume = 50.0
    @State private var theme = "Light"

    var body: some View {
        Form {
            Section("Profile") {
                TextField("Name", text: $name)
            }
            Section("Preferences") {
                Toggle("Notifications", isOn: $notifications)
                Slider(value: $volume, in: 0...100)
                Picker("Theme", selection: $theme) {
                    Text("Light").tag("Light")
                    Text("Dark").tag("Dark")
                }
            }
        }
    }
}

Common input controls

  • TextField / SecureField — text and password entry.
  • Toggle — an on/off switch.
  • Picker — choose one option from a list.
  • Slider / Stepper — pick a number.
  • DatePicker — choose a date/time.

Each binds to state with $, so the value and the UI stay in sync automatically — the same two-way binding idea you learned earlier.

Validating input

You can compute whether the form is valid from your state and disable the submit button until it is:

var isValid: Bool {
    !name.isEmpty && name.count >= 2
}

Button("Save") { save() }
    .disabled(!isValid)        // greyed out until valid

Keyboard handling

You can customise the keyboard and focus. For example, set the keyboard type for an email field and move focus between fields with @FocusState:

TextField("Email", text: $email)
    .keyboardType(.emailAddress)
    .textInputAutocapitalization(.never)

Common mistakes

  • Forgetting $ on the binding, so the control doesn’t update your state.
  • Not disabling the submit button for invalid input.
  • Not setting the right keyboardType (e.g. numbers, email).
Summary: Use Form with bound controls (TextField, Toggle, Picker, Slider, DatePicker) for native data entry. Compute validity from state and disable actions until input is valid.