Greetings, traveler!
SwiftUI tabs used to be simple on iPhone and more awkward on iPad. On iPhone, TabView naturally mapped to a bottom tab bar. On iPad, many apps needed something closer to a sidebar: more space, grouped destinations, and a layout that feels better on a large display.
The usual answer was to build a custom sidebar, split the app into separate navigation structures, or use conditional code for iPhone and iPad. That worked, but it also meant you were responsible for keeping selection, layout, and platform behavior in sync.
.tabViewStyle(.sidebarAdaptable) changes that model. It lets a TabView adapt between a tab bar and a sidebar while still using SwiftUI’s tab API.
The newer .defaultTabBarPlacement(.sidebar) modifier gives you one more control point. It lets you prefer the sidebar placement for tabs when the TabView uses the adaptable sidebar style.
The basic idea
The API starts with a normal TabView.
struct RootView: View {
var body: some View {
TabView {
Tab("Home", systemImage: "house") {
HomeView()
}
Tab("Library", systemImage: "books.vertical") {
LibraryView()
}
Tab("Search", systemImage: "magnifyingglass") {
SearchView()
}
}
.tabViewStyle(.sidebarAdaptable)
}
}This is still a tab-based app. You are not replacing TabView with a custom container.
The difference is that SwiftUI can choose a better visual representation for the current platform and size class. On iPhone, this can still look like a regular tab bar. On iPad, the same structure can become a sidebar-based navigation surface.
That is the important part: you describe the app destinations once, and SwiftUI decides how those destinations should be presented.
Where .defaultTabBarPlacement(.sidebar) fits
.sidebarAdaptable enables the adaptive style.
.defaultTabBarPlacement(.sidebar) tells SwiftUI which placement you prefer by default.
struct RootView: View {
var body: some View {
TabView {
Tab("Home", systemImage: "house") {
HomeView()
}
Tab("Library", systemImage: "books.vertical") {
LibraryView()
}
Tab("Search", systemImage: "magnifyingglass") {
SearchView()
}
}
.tabViewStyle(.sidebarAdaptable)
.defaultTabBarPlacement(.sidebar)
}
}You are saying: when this tab view can use the adaptable sidebar style, start from the sidebar placement. SwiftUI still owns the platform behavior.
Do not forget the NavigationStack
There is one practical detail that is easy to miss. The sidebar button appears in the navigation area. If a tab contains a plain view without a navigation container, SwiftUI may have no visible navigation bar where it can place that control.
So in a real app, each tab should usually own its own NavigationStack and provide a navigation title.
struct RootView: View {
var body: some View {
TabView {
Tab("Dashboard", systemImage: "speedometer") {
NavigationStack {
List {
Text("View Reports")
Text("Check Tasks")
Text("Team Activity")
}
.navigationTitle("Dashboard")
}
}
Tab("Messages", systemImage: "bubble.left.and.bubble.right") {
NavigationStack {
List(["Alice", "Bob", "Charlie"], id: \.self) { name in
NavigationLink {
Text("Chat with \(name)")
} label: {
Text(name)
}
}
.navigationTitle("Messages")
}
}
}
.tabViewStyle(.sidebarAdaptable)
.defaultTabBarPlacement(.sidebar)
}
}Why this is useful
On iPad, the old bottom tab bar often feels like an iPhone pattern stretched onto a larger screen.
You get more room for labels, better grouping, and less pressure to hide everything behind four or five tab items.
There is another reason this API is interesting.
If Apple ships a foldable iPhone, the line between iPhone and iPad layouts becomes less clean. A closed device may behave like a regular iPhone. An unfolded device may have enough space for sidebar-style navigation.
Apple has not announced such a device. But the direction of the API fits that kind of future.
A foldable iPhone would need apps that can move between compact and expanded layouts without every developer building a separate navigation system. TabView with .sidebarAdaptable is exactly the kind of API that helps with that.
That is the part I like most about this API. It does not ask you to predict every device shape.
Final thought
.tabViewStyle(.sidebarAdaptable) solves a real layout problem. It lets SwiftUI keep the same tab model across compact and expanded interfaces. .defaultTabBarPlacement(.sidebar) adds a small but useful preference on top of that model.
For iPad apps, this already makes sense. For a possible foldable iPhone, it may become even more important.
