Custom Liquid Glass tab bar

iOS 26 introduced Liquid Glass to the tab bar. It looks awesome. But it’s also impossible to customize. The only things you can change are what string and what SF Symbol the tab displays. Anything else you could want to adjust — adding a profile photo, a custom badge, or a live avatar — is impossible.

So I built UnionTabView. It looks basically identical to the system tab bar but lets you drop any view you want into a tab.1

UnionTabView: a custom character living inside the Liquid Glass tab barNone of that fake glass shit.

How to use

You give it your tabs, and a view for each slot:

import UnionTabView
 
UnionTabView(selection: $tab, tabs: Tab.allCases) {
    HomeView().unionTab(Tab.home)
    SearchView().unionTab(Tab.search)
    ProfileView().unionTab(Tab.profile)
} item: { tab, isSelected in
    Image(systemName: tab.symbol)
        .foregroundStyle(isSelected ? .primary : .secondary)
}

And because item is a @ViewBuilder, a slot can be a profile picture:

if tab == .profile {
    AsyncImage(url: user.avatarURL) { image in
        image.resizable().scaledToFill()
    } placeholder: {
        Circle().fill(.gray.opacity(0.2))
    }
    .frame(width: 28, height: 28)
    .clipShape(.circle)
} else {
    Image(systemName: tab.symbol)
}

Instagram’s tab bar is in shambles.

On older phones

Below iOS 26, there’s no Liquid Glass of course, so the package elegantly falls back to the old full tab bar appropriate for that iOS version.

UnionTabView is on GitHub. Get the package.

Note

UnionTabView is open source under the MIT license. It needs iOS 17 or later, builds with Swift 6, and installs through the Swift Package Manager.

Footnotes

  1. Almost nothing in it is fake. The glass is Apple’s .glassEffect(.regular.interactive()), the pill is a real UISegmentedControl hiding under your views with its titles emptied, and the scroll-edge fade survives because of an invisible period drawn with .blendMode(.destinationOver). The source is four small files.