Greetings, traveler!
SwiftUI gets a new tab role in iOS 27: TabRole.prominent. You can mark one tab as visually prioritized within the tab hierarchy, and SwiftUI can give it a prominent treatment in supported tab bars.
That sounds very close to a pattern many iOS developers wanted after the newer Liquid Glass tab bar design appeared. You have a normal set of tabs, but one item should stand apart. Maybe it is a “Create New Item” destination where users create content, add tasks, or start a new workflow. It is still a tab, but it is clearly more important than the others.
Before this API, you usually had two options. You either accepted the default tab bar, or you started building a custom one. And once you build a custom tab bar, the work grows quickly: selection state, safe areas, accessibility, animation, scroll behavior, platform adaptation, and all the tiny details that make system controls feel system-like.
The new role
Apple describes TabRole as a value that defines the purpose of a tab. Until now, the role most developers cared about was .search.
In iOS 27, there is also .prominent. The declaration is simple:
static var prominent: TabRole { get }You use it through one of the Tab initializers that accepts a role parameter:
Tab("Now", systemImage: "play.fill", value: .nowPlaying, role: .prominent) {
NowPlayingView()
}Or with a custom label:
Tab(value: .nowPlaying, role: .prominent) {
NowPlayingView()
} label: {
Label("Now", systemImage: "play.fill")
}Only one tab can receive the prominent treatment.
What happens with search?
In iOS 26, .search already had special behavior in tab-based interfaces. Depending on the context, the search tab could be visually separated from the rest of the tab bar.
There is one detail from the documentation worth remembering: if your TabView does not contain a tab with an explicit .prominent role, then a .search role tab may receive the prominent visual treatment by default.
So in this example:
Tab(value: .nowPlaying, role: .prominent) {
NowPlayingView()
} label: {
Label("Now", systemImage: "play.fill")
}
Tab(value: .search, role: .search) {
SearchView()
} label: {
Label("Search", systemImage: "magnifyingglass")
}the prominent tab is nowPlaying, because you marked it explicitly.
The search tab is still the search tab, but it is not the one receiving the prominent treatment. If you remove .prominent, then SwiftUI may use the .search tab as the prominent one by default:
Tab(value: .nowPlaying) {
NowPlayingView()
} label: {
Label("Now", systemImage: "play.fill")
}
Tab(value: .search, role: .search) {
SearchView()
} label: {
Label("Search", systemImage: "magnifyingglass")
}Example
Here is a small TabView with one prominent tab:
enum RootTab: Hashable {
case home, library, nowPlaying
}
struct RootView: View {
@State private var selection: RootTab = .home
var body: some View {
TabView(selection: $selection) {
Tab("Home", systemImage: "house", value: .home) {
HomeView()
}
Tab("Library", systemImage: "music.note.list", value: .library) {
LibraryView()
}
Tab("Now", systemImage: "play.fill", value: .nowPlaying, role: .prominent) {
NowPlayingView()
}
}
}
}Availability
TabRole.prominent is an iOS 27 beta API. If your app supports older OS versions, you need to guard the usage:
if #available(iOS 27.0, *) {
Tab("Now", systemImage: "play.fill", value: .nowPlaying, role: .prominent) {
NowPlayingView()
}
} else {
Tab("Now", systemImage: "play.fill", value: .nowPlaying) {
NowPlayingView()
}
}Final thoughts
TabRole.prominent gives SwiftUI a native way to express one special tab without immediately falling into a custom tab bar implementation.
