TechnologiesSwiftUI

DisclosureGroupStyle protocol

iOSmacOStvOSwatchOSvisionOS✓ renders

A type that specifies the appearance and interaction of disclosure groups

How it works

DisclosureGroupStyle is the protocol that defines the appearance and interaction behavior of a DisclosureGroup — the disclosure triangle, its label, and how the content collapses and expands. Conform a type to it, or pick one of the built-in styles, to customize that presentation everywhere a disclosure group appears in a view hierarchy. Reach for it when the default disclosure look doesn't fit your design and you want a single reusable style that you can apply across many groups rather than restyling each one by hand.

  1. Apply a style with disclosureGroupStyle(_:)

    The disclosureGroupStyle(_:) modifier takes any value conforming to DisclosureGroupStyle and applies it to every DisclosureGroup in the subtree. In the example, .disclosureGroupStyle(.automatic) sets the style on the group that holds the "Advanced Settings" toggles; swap in a different style value and the modifier re-skins the group without touching its content.

  2. Start from the built-in .automatic style

    DisclosureGroupStyle provides ready-made values so you don't have to write a style for the common case. .automatic resolves to the platform-appropriate disclosure presentation — the standard triangle-and-label layout — and is what the example uses as a baseline before you customize further.

  3. Define a custom style by conforming to the protocol

    To go beyond the built-ins, declare a type that conforms to DisclosureGroupStyle and implement its makeBody(configuration:) requirement, returning the view that draws the group. You apply it the same way through disclosureGroupStyle(_:), so the DisclosureGroup("Advanced Settings", isExpanded: $isExpanded) call site stays unchanged.

  4. Read state from the Configuration

    Inside makeBody(configuration:), the style receives a configuration value exposing the group's label, its content, and an isExpanded binding. That binding mirrors the same expanded state the example drives with @State private var isExpanded = true and $isExpanded, letting your custom style render and toggle the open/closed appearance itself.

Try it — Replace .disclosureGroupStyle(.automatic) with your own type conforming to DisclosureGroupStyle and watch the disclosure triangle around "Advanced Settings" redraw the way your makeBody(configuration:) describes.

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.

DisclosureGroupStyle.swift
struct DisclosureGroupStyleDemo: 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))
            Toggle("AirDrop", isOn: .constant(true))
        }
        .disclosureGroupStyle(.automatic)
        .padding()
    }
}
Live preview
Advanced Settings Wi-Fi Bluetooth AirDrop
Advanced Settings Wi-Fi Bluetooth AirDrop
swift → lexer → parser → sema → uiir → canvas Open in Studio ↗
What's new in SwiftUI 27 →