TechnologiesSwiftUI

TabSectionExpansion struct

iOSmacOStvOSwatchOSvisionOS✓ renders

The default expansion state for a tab section in the sidebar.

How it works

TabSectionExpansion is the value type that records whether a TabSection inside a sidebar-adaptable TabView is currently expanded or collapsed. SwiftUI exposes a section's disclosure state through this type so your code can observe it and drive it, rather than leaving expansion entirely to the user's taps in the sidebar. Reach for it when you bind a TabSection's expansion to your own state — for example to remember which groups a person opened, to expand a section programmatically when its content becomes relevant, or to keep several sections in sync. Its two states are spelled .expanded and .collapsed.

  1. Group tabs with TabSection so an expansion state exists

    TabSectionExpansion only has meaning for a collapsible group, which is what TabSection provides. In the example the TabSection("Library") wraps the "Songs" and "Albums" tabs into a single titled group; that grouping is the disclosure container whose open/closed state TabSectionExpansion describes.

  2. Render in a style that draws sections as disclosable

    A section can only expand or collapse when the TabView is presented as a sidebar. Applying .tabViewStyle(.sidebarAdaptable) is what turns TabSection("Library") into a collapsible disclosure group on platforms with room for a sidebar, giving TabSectionExpansion a real expanded-versus-collapsed state to track.

  3. Bind expansion with the TabSection initializer

    To control or observe a group's disclosure, use the TabSection initializer that takes an expansion binding and store a TabSectionExpansion value in your own @State. You would add a property such as @State private var libraryExpansion: TabSectionExpansion = .expanded and pass $libraryExpansion to the TabSection("Library") initializer so SwiftUI reads and writes it as the user toggles the section.

  4. Read and set the .expanded and .collapsed cases

    TabSectionExpansion is an enumeration-like value with the cases .expanded and .collapsed. Once it is bound to TabSection("Library"), setting the bound state to .collapsed folds the "Songs" and "Albums" tabs away, while assigning .expanded reveals them, and comparing the value lets you react when a person opens or closes the group.

  5. Keep section affordances available across states

    Modifiers attached to the section, like the .sectionActions block holding the Button("Add", systemImage: "plus"), belong to the TabSection whose expansion you are tracking. Because TabSectionExpansion controls only the disclosure of the section's tabs, such header actions remain part of the same TabSection("Library") group you bind the expansion to.

Try it — Add @State private var libraryExpansion: TabSectionExpansion = .collapsed and pass $libraryExpansion to TabSection("Library"), then watch the Songs and Albums tabs start hidden until you flip the value to .expanded.

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.

TabSectionExpansion.swift
struct TabSectionExpansionDemo: View {
    @State private var selection = "home"
    var body: some View {
        TabView(selection: $selection) {
            Tab("Home", systemImage: "house", value: "home") {
                Text("Home").padding()
            }
            TabSection("Library") {
                Tab("Songs", systemImage: "music.note", value: "songs") {
                    Text("Songs").padding()
                }
                Tab("Albums", systemImage: "square.stack", value: "albums") {
                    Text("Albums").padding()
                }
            }
            .sectionActions {
                Button("Add", systemImage: "plus") {}
            }
        }
        .tabViewStyle(.sidebarAdaptable)
        .padding()
    }
}
Live preview
Home Home Tab 2
Home Home Tab 2
swift → lexer → parser → sema → uiir → canvas Open in Studio ↗
What's new in SwiftUI 27 →