Form in SwiftUI: What It Is, Creating and Configuring Forms

Author: IT Sectr Published: 2026-06-25 Reading time: 8 min

Form in SwiftUI is a container component for building structured settings and data input interfaces, following the design of Settings in iOS. The component automatically groups controls into sections with system spacing and styles, freeing the developer from manual adjustment of separators and colors. According to Apple Developer Documentation (2025), Form adapts its appearance to each platform — from grouped tables on iOS to standard lists on macOS — while maintaining a unified API.

Key Takeaways

  • Form — a container for Settings-like interfaces in SwiftUI with automatic element grouping
  • Section inside Form creates logical blocks with headers and footers
  • Picker, Toggle, TextField automatically get a style matching the platform
  • Spacing and separators are managed by the system, requiring no manual configuration
  • NavigationLink allows creating hierarchical forms with navigation to child screens

What Is Form in SwiftUI?

Form is a specialized SwiftUI container designed for creating input forms and settings screens. It inherits the behavior of List but adds platform-specific styles: on iOS, Form displays as a grouped table with rounded section corners; on macOS, it appears as a standard system list with checkboxes and controls.

Unlike manual layout with VStack and HStack, Form automatically arranges spacing between elements, adds separators, and adapts its appearance to the system theme — light or dark. The developer only describes the logical structure: Section for grouping and controls inside. The form itself decides how to visually arrange Picker, Toggle, or Stepper on a specific platform.

Form supports all standard SwiftUI input elements: TextField for text, SecureField for passwords, Picker for list selection, Toggle for on/off, Slider for ranges, Stepper for incremental values, and DatePicker for dates. Each element automatically gets a style matching Apple's HIG (Human Interface Guidelines) on the target platform.

Form vs List: Container Comparison

Despite their visual similarity, Form and List solve different tasks. List is a universal container for displaying scrollable data lists with swipe actions and row editing capabilities. Form is a specialized container for data input and settings, optimized for system control styles.

List is suitable for displaying dynamic data: news feeds, chats, product catalogs. Form is for static screens with a predictable set of fields: user profile, app settings, registration form. The key difference: Form elements can be interactive controls, whereas List rows mostly display data and respond to tap with navigation or action.

ParameterFormList
PurposeData input, settingsList display
Section styleGrouped (iOS), system (macOS)Plain or Grouped
ControlsPicker, Toggle, Slider, StepperLimited (button)
Dynamic dataLimited (ForEach inside Section)Full support
Swipe actionsYes, swipeActionsYes, swipeActions

According to Apple Human Interface Guidelines (2025), Form should be used for settings and input screens where there are 3 to 20 controls on one screen and dividing them into sections improves usability.

Section Inside Form

Section is the main building block of Form, allowing logically related elements to be grouped together. Each Section can have a header, footer, and any number of controls inside. The system automatically adds spacing between sections and wraps each one in a visual block with rounded corners.

Using Section is critical for form readability: elements grouped by meaning are easier for the user to process. For example, on a profile settings screen, you can separate «Personal Data», «Notifications», and «Security» into individual sections. Each section can contain a footer with explanatory text, which the system displays in a smaller font below the group of elements.

swift
Form {
    Section(header: Text("Profile")) {
        TextField("Name", text: $name)
        TextField("Email", text: $email)
    }

    Section(header: Text("Notifications"),
            footer: Text("Disable during meetings")) {
        Toggle("Push notifications", isOn: $pushEnabled)
        Toggle("Email notifications", isOn: $emailEnabled)
    }
}

In the example, the first section «Profile» contains two text fields without a footer, the second section «Notifications» contains two toggles with an explanation below the group. The footer automatically adds spacing and uses the caption font style. A Section can have a footer without a header or a header without a footer.

Form Controls

Form supports all standard SwiftUI input elements. Picker in Form automatically displays as a navigation row with a transition to a separate selection screen on iOS. Toggle appears as a row with a switch aligned to the right. TextField gets the system input style with a placeholder.

For numeric values, Stepper (incremental change) and Slider (smooth range change) are used. DatePicker supports several modes: date, time, dateAndTime. ColorPicker is available for color selection. Each element adapts to the platform without additional code — on iOS, controls use native UIKit styles; on macOS, AppKit.

ElementPurposeForm Style
TextFieldText inputRow with placeholder
SecureFieldPassword inputRow with hidden characters
PickerList selectionNavigationLink to selection screen
ToggleOn/OffRow with switch
SliderValue rangeHorizontal slider
DatePickerDate/time selectionCompact or wheel style

For custom controls inside Form, any SwiftUI View can be used — they inherit the standard section behavior. However, it is recommended to stick with system elements, as they guarantee HIG compliance and support Accessibility (VoiceOver, Dynamic Type) without additional configuration.

Form Code Examples

Let's create a registration screen using Form. The form contains four sections: personal data, role selection, subscription settings, and a submit button. Section is used for grouping and standard SwiftUI controls.

swift
struct RegistrationForm: View {
    @State private var name = ""
    @State private var email = ""
    @State private var role = "Developer"
    @State private var agreedToTerms = false

    let roles = ["Developer", "Designer", "Manager"]

    var body: some View {
        NavigationStack {
            Form {
                Section(header: Text("Personal Info")) {
                    TextField("Name", text: $name)
                    TextField("Email", text: $email)
                        .keyboardType(.emailAddress)
                }

                Section(header: Text("Role")) {
                    Picker("Select role", selection: $role) {
                        ForEach(roles, id: \.self) { role in
                            Text(role).tag(role)
                        }
                    }
                }

                Section {
                    Toggle("Agree to terms", isOn: $agreedToTerms)
                }

                Section {
                    Button("Register") {
                        submitForm()
                    }
                    .disabled(!agreedToTerms)
                }
            }
            .navigationTitle("Registration")
        }
    }

    private func submitForm() { }
}

The form is divided into four Section blocks: personal data with two text fields, role selection via Picker, agreement to terms via Toggle, and a registration button. The button is disabled until the user agrees to the terms — this is an example of validation inside Form. NavigationStack adds a title and allows Picker to open a separate selection screen on iOS.

Settings Form with Subsections

swift
struct SettingsForm: View {
    @State private var volume: Double = 0.5
    @State private var isDarkMode = false
    @State private var reminderDate = Date()

    var body: some View {
        NavigationStack {
            Form {
                Section(header: Text("Appearance")) {
                    Toggle("Dark mode", isOn: $isDarkMode)
                    Slider(value: $volume, in: 0...1) {
                        Text("Volume")
                    }
                }

                Section(header: Text("Reminders"),
                        footer: Text("You'll get a notification at the selected time")) {
                    DatePicker("Remind at",
                        selection: $reminderDate,
                        displayedComponents: .hourAndMinute)
                }

                Section {
                    NavigationLink("Advanced Settings",
                        destination: AdvancedSettingsView())
                }
            }
            .navigationTitle("Settings")
        }
    }
}

This example demonstrates a combination of Slider, DatePicker, and NavigationLink inside Form. DatePicker uses the hourAndMinute mode to display only the time. NavigationLink in the last section creates a transition to an advanced settings screen — a common pattern for Settings-like interfaces. Section headers and footers make the form self-documenting: the user immediately understands which group each control belongs to.

Frequently Asked Questions

What is the difference between Form and List in SwiftUI?

Form is optimized for data input and settings: controls get system styles, sections get rounded corners and spacing. List is a universal container for data display. Form is suitable for settings screens, List is for chats, feeds, catalogs.

Can Picker be used inside Form?

Yes, Picker inside Form automatically displays as a row with the selected value and a NavigationLink for list selection on iOS. On macOS, Picker appears as a dropdown list or radio group depending on the style. Adaptation happens without additional code.

How to add a custom View to Form?

Any SwiftUI View can be placed inside Form or Section. For custom controls, it is recommended to inherit standard section spacing and support Dynamic Type through system fonts. Avoid fixed sizes and colors so the form displays correctly on all devices.

Does Form support scrolling?

Yes, Form is automatically wrapped in a ScrollView if the content exceeds the screen height. There is no need to add ScrollView manually — the system itself determines whether scrolling is needed. For forms that should not scroll, use VStack with a fixed height.

How to change Form style on iOS?

Form on iOS supports two styles via the .formStyle(.grouped) modifier — the standard grouped view with rounded sections. On macOS, .formStyle(.columns) is available with multi-column layout. The style applies to the entire Form at once and changes the visual representation of all elements inside.

Summary

  • Form — SwiftUI container for Settings-like interfaces with automatic grouping via Section
  • Section provides logical separation of elements with headers and footers
  • Picker, Toggle, TextField automatically adapt to the platform style without manual configuration
  • Spacing and separators are managed by the system, conforming to Apple HIG on each platform
  • NavigationLink inside Form creates hierarchical navigation — standard for settings screens
  • Form supports all SwiftUI input elements: Slider, Stepper, DatePicker, ColorPicker
  • Use Form for settings and input screens, List for displaying dynamic data lists

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also