TechnologiesSwiftUI

TabViewBottomAccessoryPlacement enum

iOSmacOStvOSwatchOSvisionOSiOS 26.0+✓ renders

A placement of the bottom accessory in a tab view. You can use this to

How it works

TabViewBottomAccessoryPlacement is an enumeration that describes where the accessory you attach above a tab bar is currently being shown. When you add a view with the tabViewBottomAccessory modifier, SwiftUI may render it inline alongside the tab bar or promote it into an expanded region, depending on the platform, available space, and tab-bar state. Read this value from the environment so the accessory can adapt its layout and content to the room it has been given, rather than guessing. Reach for it whenever a persistent bottom accessory — a now-playing bar, a mini player, a status strip — needs to look right in both its compact and expanded forms.

  1. Attach the accessory with tabViewBottomAccessory(_:)

    The placement value only exists because a view has been installed as a tab-bar accessory. Applying .tabViewBottomAccessory to the TabView hands SwiftUI the content — here NowPlayingBar() — that sits in the accessory slot and whose placement the system then reports.

  2. Read the placement from the environment

    SwiftUI publishes the current placement through the tabViewBottomAccessoryPlacement environment value. Inside the accessory, @Environment(\.tabViewBottomAccessoryPlacement) private var placement binds it to a property, so the view receives a fresh TabViewBottomAccessoryPlacement whenever the system moves the accessory between layouts.

  3. Branch on the enum's cases

    Because it is an enum, you compare placement against its cases to drive layout decisions. The example tests placement == .expanded to decide how much detail to show, choosing the fuller "Now Playing — Expanded" label when the accessory has been promoted and the compact "Now Playing" label otherwise.

  4. Let the value re-render the accessory

    Since the placement arrives through the environment, any change re-evaluates the accessory's body automatically. The HStack of Image and Text in NowPlayingBar recomputes its content as the placement updates, so the same accessory presents the right amount of information in each form.

Try it — Add a third case branch — or swap the ternary in Text(placement == .expanded ? ... : ...) to also append the placement's name — to watch the label change as the system moves NowPlayingBar between its inline and expanded placements.

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.

TabViewBottomAccessoryPlacement.swift
struct TabViewBottomAccessoryPlacementDemo: View {
    var body: some View {
        TabView {
            Tab("Home", systemImage: "house") {
                Text("Home").padding()
            }
            Tab("Search", systemImage: "magnifyingglass") {
                Text("Search").padding()
            }
        }
        .tabViewBottomAccessory {
            NowPlayingBar()
        }
    }
}

struct NowPlayingBar: View {
    @Environment(\.tabViewBottomAccessoryPlacement) private var placement

    var body: some View {
        HStack {
            Image(systemName: "music.note")
            Text(placement == .expanded ? "Now Playing — Expanded" : "Now Playing")
            Spacer()
            Image(systemName: "play.fill")
        }
        .padding()
    }
}
Live preview
Home Home Home
Home Home Home
swift → lexer → parser → sema → uiir → canvas Open in Studio ↗
What's new in SwiftUI 27 →