Forms & User Input
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: UseFormwith bound controls (TextField,Toggle,Picker,Slider,DatePicker) for native data entry. Compute validity from state and disable actions until input is valid.