Section in SwiftUI is a container component for logically grouping elements inside Form or List. It displays content as a visual block with system spacing, rounded corners, and optional header and footer. According to Apple Developer Documentation (2025), Section does not manage data — it only organizes the presentation: all child elements inherit its style and spacing, providing structured display of forms and lists.
Key Takeaways
Section is a structural SwiftUI component designed for grouping elements inside Form and List containers. Unlike VStack or HStack, Section adds system spacing, a header and footer, as well as visual group highlighting in the form of a rounded-corner block on iOS.
Section does not change the behavior of child elements — it only organizes their presentation. All controls inside a Section — Picker, Toggle, TextField — work as usual, but are visually combined into a logical group. This is especially important for on-screen forms where the user needs to quickly navigate the data entry structure.
The system automatically manages spacing between sections: the distance between Sections on iOS is 16–20 points, between elements inside a Section is 0 (separator between rows). The developer cannot change these spacings through padding modifiers — they are controlled by the system to ensure a consistent appearance.
Section accepts two optional parameters: header — the group title, and footer — explanatory text below the group. The header is displayed above the section elements in bold caption-style font, the footer in a smaller font with gray color. Both parameters accept any SwiftUI View, not just Text.
A Section header helps the user understand which category the elements inside the group belong to. For example, on a settings screen, headers like “Notifications”, “Privacy” and “Account” instantly orient the user. Footer is useful for explanations: “Turn off notifications during meetings” or “Password must contain at least 8 characters.” The footer automatically wraps to multiple lines when needed.
Section(
header: Text("Account Security"),
footer: Text("Use a strong password with at least 8 characters.")
) {
SecureField("Current password", text: $currentPassword)
SecureField("New password", text: $newPassword)
}
In the example, Section has the header “Account Security” and a footer with password security advice. The user sees the header as a section label, fills in two fields, and immediately reads the warning below them. This structure improves UX because all information about the section is on one screen without needing to navigate to a separate help page.
Section works both inside Form and List, but the visual representation differs. In Form, Section is displayed as a block with rounded corners and system background, separated from adjacent sections by spacing. In List, Section can use the plain style — without background and rounded corners, or inset-grouped — with rounded blocks similar to Form.
The choice of container affects the Section style. If you place a Section with the same content inside Form and List with .insetGrouped style, the result will be identical. However, Form adds system spacing and uses grouped style by default, while List requires explicit style specification through the .listStyle(.insetGrouped) modifier.
| Container | Default Section | Available Styles |
|---|---|---|
| Form | InsetGrouped with rounded corners | .grouped (Form only) |
| List | Plain — no section background | .plain, .inset, .insetGrouped, .sidebar |
To achieve the same appearance in List, use .listStyle(.insetGrouped). This style mimics the Form appearance and is suitable for settings screens built on List. For standard data lists, use .plain — without section highlighting, with thin separators between rows.
Section can contain a dynamic number of elements through ForEach. This allows creating groups with repeating elements while preserving the header and footer for the entire group. ForEach inside Section iterates over a data collection and creates child Views for each element without breaking the section structure.
Dynamic sections are useful for settings screens with a variable number of options: a list of available languages, connected devices, or push subscriptions. The section header remains static while the content changes depending on the data.
struct DynamicSectionView: View {
let categories = ["Work", "Personal", "Finance", "Health"]
@State private var selected = Set<String>()
var body: some View {
Form {
Section(header: Text("Categories"),
footer: Text("Select your preferred categories")) {
ForEach(categories, id: \.self) { category in
Toggle(category, isOn: Binding(
get: { selected.contains(category) },
set: { if $0 { selected.insert(category) }
else { selected.remove(category) } }
))
}
}
Section {
Text("Selected: \(selected.count) categories")
.foregroundStyle(.secondary)
}
}
}
}
In this example, ForEach generates a Toggle for each category from the categories array. The section header and footer are set once and apply to the entire group. The second section displays the number of selected categories — it does not depend on ForEach and remains static. This approach allows creating flexible forms where the header and footer contextualize a group of dynamic elements.
Let’s look at a complete profile screen example using Section for data grouping. The form contains three sections: user information, privacy settings, and statistics. Each section uses its own header, and the last one has a footer with summary information.
struct ProfileView: View {
@State private var displayName = "Alex Johnson"
@State private var bio = "iOS developer"
@State private var isProfilePublic = true
@State private var showEmail = false
var body: some View {
Form {
Section(header: Text("Profile Info")) {
TextField("Display name", text: $displayName)
TextField("Bio", text: $bio, axis: .vertical)
.lineLimit(3)
}
Section(header: Text("Privacy")) {
Toggle("Public profile", isOn: $isProfilePublic)
Toggle("Show email", isOn: $showEmail)
.disabled(!isProfilePublic)
}
Section(header: Text("Stats"),
footer: Text("Last updated today at 2:30 PM")) {
LabeledContent("Posts", value: "42")
LabeledContent("Followers", value: "1,280")
LabeledContent("Following", value: "346")
}
}
.navigationTitle("Profile")
}
}
Three Section blocks clearly separate functional areas: editable profile fields, privacy toggles, and statistics. The second section demonstrates validation: the “Show email” toggle is disabled until the profile is public. The footer of the third section shows the last update time — an example of using a footer for additional contextual information. LabeledContent is a standard SwiftUI component for displaying key-value pairs in Form.
Section(
header: HStack {
Image(systemName: "bell.fill")
.foregroundStyle(.blue)
Text("Notifications")
.font(.headline)
},
footer: Text("Manage push and email alerts")
) {
Toggle("Push notifications", isOn: $push)
Toggle("Email notifications", isOn: $email)
Stepper("Quiet hours: \(quietStart) — \(quietEnd)",
value: $quietStart,
in: 0...23)
}
This example shows that header can be any SwiftUI View. Using HStack with Image and Text adds an icon next to the header, making the section visually more expressive. Custom headers are useful for highlighting important sections in the interface: notification settings, paid features, or sections with warnings. However, overusing custom headers is not recommended — 1–2 sections with non-standard styling per screen is enough to maintain interface consistency.
Frequently Asked Questions
No, Section does not support nesting in SwiftUI. Attempting to place a Section inside another Section causes a compilation error. For hierarchical grouping, use List with OutlineGroup or DisclosureGroup inside a Section.
Spacing between Sections is managed by the system and cannot be changed through padding modifiers. On iOS, the distance between sections is 16–20 points and follows HIG. The only way to affect spacing is to use a custom ListStyle, but this is not recommended.
Group is an invisible container for grouping elements without visual styling. Section adds a header, footer, spacing and a visual block. Group is used for conditional rendering, Section for structuring the interface.
Yes, Section automatically adds accessibility labels. The section header becomes an accessibility header for the group, the footer becomes an accessibility hint. VoiceOver reads the header before entering the section, improving navigation for users with disabilities.
No, Section only works inside Form or List. Using Section outside these containers causes a compilation error. For grouping elements in VStack or ScrollView, use Group or custom Views with manual spacing configuration.
Summary
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.
Read also