TechnologiesSwiftUI

DisclosureGroup struct

iOSmacOStvOSwatchOSvisionOS✓ renders

A view that shows or hides another content view, based on the state of a

How it works

A DisclosureGroup is a view that shows or hides its content behind a label the person can tap to expand or collapse. Use it to defer secondary or advanced controls until they're needed, keeping a screen uncluttered while still making everything reachable. It's the natural choice for optional settings, detail sections, and any group of views that doesn't need to be visible at all times. Because expansion is a piece of view state, you can either let DisclosureGroup manage it automatically or bind it to your own property to control and observe it.

  1. Give the group a label and content with init(_:isExpanded:content:)

    The initializer takes a title for the always-visible header and a content closure holding the views to disclose. Here DisclosureGroup("Advanced Settings", isExpanded: $isExpanded) labels the header, and its trailing closure supplies the two Toggle rows and the Text that appear only when expanded.

  2. Drive expansion with the isExpanded binding

    The isExpanded parameter takes a Binding<Bool> so expansion lives in your own state. Backing it with @State private var isExpanded = true and passing $isExpanded lets the group start open and lets your code read or change whether it's expanded; omit this argument and DisclosureGroup manages the state internally instead.

  3. Compose any views inside the content closure

    Whatever you place in the content closure becomes the disclosed body, built with the standard view builder. This example discloses interactive Toggle("Wi-Fi", isOn:) and Toggle("Bluetooth", isOn:) controls alongside a plain Text, showing that the hidden section can hold real, fully functional views, not just labels.

  4. Style the disclosed content like any view

    Views inside the group accept the usual modifiers, so you can shape the revealed section independently of the header. The Text("Airplane Mode is off") here uses .foregroundStyle(.secondary) to read as supporting detail, while .padding() on the DisclosureGroup itself insets the whole control.

Try it — Change @State private var isExpanded = true to false so the group starts collapsed, then tap the "Advanced Settings" header to watch the Toggle rows disclose.

Example & preview

Press Run live & edit to compile it in your browser — then edit the Swift on the left and the preview re-renders live.

DisclosureGroup.swift
struct DisclosureGroupDemo: View {
    @State private var isExpanded = true

    var body: some View {
        DisclosureGroup("Advanced Settings", isExpanded: $isExpanded) {
            Toggle("Wi-Fi", isOn: .constant(true))
            Toggle("Bluetooth", isOn: .constant(false))
            Text("Airplane Mode is off")
                .foregroundStyle(.secondary)
        }
        .padding()
    }
}
Live preview
Advanced Settings Wi-Fi Bluetooth Airplane Mode is off
Advanced Settings Wi-Fi Bluetooth Airplane Mode is off
swift → lexer → parser → sema → uiir → canvas Open in Studio ↗
What's new in SwiftUI 27 →