In iOS 18, TabView with .tabViewStyle(.sidebarAdaptable) introduced a powerful adaptive pattern — tabs in compact, sidebar in regular. However, the current Tab API only supports a title and an image (icon). There is no way to provide a trailing accessory view (e.g., a secondary icon or indicator) for sidebar rows.
This is a meaningful gap in the API, because trailing accessories are a well-established pattern throughout UIKit and SwiftUI.
Precedent in Apple's own design language Apple already supports trailing accessories in many analogous contexts:
- UITableViewCell / UICollectionViewListCell — support accessories (disclosure indicators, checkmarks, custom views) via UICellAccessory.
- UIListContentConfiguration — allows leading and trailing content in list rows.
- SwiftUI List rows — support Label, HStack with trailing elements, .badge(), and swipeActions.
- NavigationLink — automatically renders a disclosure chevron as a trailing accessory.
- UITabSidebarItem (UIKit, iOS 18) — supports configurationUpdateHandler and cell accessories at the UIKit level.
The sidebar of a .sidebarAdaptable TabView is visually identical to a List — yet its rows lack the accessory support that List rows have had for years.
Real-world example: Photos app Apple's own Photos app (iPadOS 18+) demonstrates this exact need. In its sidebar, the "Recently Deleted" row displays a trailing lock icon to indicate that authentication is required to view the album. This is a meaningful UX element — it communicates state at a glance, without requiring the user to tap into the item.
Third-party developers building with TabView(.sidebarAdaptable) have no public API to replicate this pattern. The Tab view builder's label closure is decomposed into a discrete title and image; any additional views (including Spacer() and trailing Image views within an HStack) are silently discarded by the system.
What we've tried
- Custom label closure with HStack — trailing views are ignored. The system extracts only the first Image and Text.
- .badge() modifier — only supports Int or Text, not custom views such as icons.
- Label with complex content — the system normalizes it to icon + title.
The only viable path today is to bridge to UIKit's UITabBarController and customize UITabSidebarItem directly, which defeats the purpose of using SwiftUI's declarative TabView API.
Proposed API
A trailing accessory modifier on Tab, consistent with existing SwiftUI patterns:
Tab("Recently Deleted", systemImage: "trash", value: "deleted") {
RecentlyDeletedView()
}
.tabSidebarAccessory {
Image(systemName: "lock.fill")
.foregroundStyle(.secondary)
}
// Option B: Text accessory (e.g., counts, status labels)
Tab("Inbox", systemImage: "tray", value: "inbox") {
InboxView()
}
.tabSidebarAccessory {
Text("12")
.font(.subheadline)
.foregroundStyle(.secondary)
}
// Option C: Combined text + image accessory
Tab("Shared Albums", systemImage: "rectangle.stack", value: "shared") {
SharedAlbumsView()
}
.tabSidebarAccessory {
HStack(spacing: 4) {
Text("3 new")
.font(.caption)
.foregroundStyle(.secondary)
Image(systemName: "person.2.fill")
.foregroundStyle(.blue)
}
}
Environment
Platform: iPadOS / macOS Catalyst
iOS version: 18.0+
Xcode: 16.0+
Component: SwiftUI TabView with .tabViewStyle(.sidebarAdaptable)
Summary
The Tab API should support trailing accessory content for sidebar rows, bringing it in line with the accessory support already available in UITableViewCell, UICollectionViewListCell, UIListContentConfiguration, and SwiftUI List. Apple's own Photos app demonstrates the need for this capability, yet no public API exists for third-party developers to achieve it.