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.
Attach the accessory with tabViewBottomAccessory(_:)
The placement value only exists because a view has been installed as a tab-bar accessory. Applying
.tabViewBottomAccessoryto theTabViewhands SwiftUI the content — hereNowPlayingBar()— that sits in the accessory slot and whose placement the system then reports.Read the placement from the environment
SwiftUI publishes the current placement through the
tabViewBottomAccessoryPlacementenvironment value. Inside the accessory,@Environment(\.tabViewBottomAccessoryPlacement) private var placementbinds it to a property, so the view receives a freshTabViewBottomAccessoryPlacementwhenever the system moves the accessory between layouts.Branch on the enum's cases
Because it is an enum, you compare
placementagainst its cases to drive layout decisions. The example testsplacement == .expandedto 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.Let the value re-render the accessory
Since the placement arrives through the environment, any change re-evaluates the accessory's
bodyautomatically. TheHStackofImageandTextinNowPlayingBarrecomputes its content as the placement updates, so the same accessory presents the right amount of information in each form.
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.
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()
}
}