Tabs and iPad

Declare tab stacks, search and action bubbles, iPad sidebars, badges, and accessories.

A tab shell gives every main destination its own navigation stack:

Main.cs
.Tabs(tabs => tabs
    .LargeTitles()
    .Tab<HomeView>("Home", "house")
    .Tab<LibraryView>("Library", "books.vertical")
    .Search<SearchView>())

Tab, group, and bubble icons accept local ImageSource values. A plain string tries an SF Symbol first and then a bundle asset, so the concise calls above remain valid; use ImageSource.Bundle(...) when the source must be explicit. The title is also the identifier used by INavigator.SelectTabAsync.

Search<TView>() creates the system search destination. On iOS 18 it appears as a normal tab; on iOS 26 it uses the separated search presentation. Bubble<TView>() uses that separated position for another destination on iOS 26 and falls back to a normal tab on iOS 18. Bubble(title, icon, action) creates an action instead, and the ViewModel overload resolves an ICommand from dependency injection and accepts an optional command parameter. Its iOS 18 fallback looks like a normal tab but runs the action without changing the selected page. Search and Bubble are mutually exclusive.

iPad sidebar

OnPad changes only the iPad arrangement:

.Tabs(tabs => tabs
    .Tab<HomeView>("Home", "house")
    .Tab<LibraryView>("Library", "books.vertical")
    .OnPad(pad => pad
        .Sidebar()
        .PlaceTab<HomeView>(TabPlacement.Locked)
        .Tab<InsightsView>(
            "Insights",
            "chart.bar",
            TabPlacement.Optional)
        .Group("Collections", "square.grid.2x2", group => group
            .Tab<AlbumsView>("Albums", "rectangle.stack")
            .Tab<ArtistsView>("Artists", "music.mic"))))

Automatic, Pinned, Optional, SidebarOnly, and Locked control how a destination participates in the customizable iPad tab/sidebar interface. iPad-only tabs do not exist on iPhone; provide another navigation path if the content must remain available there. Groups are sidebar sections and can be nested.

Badges and reselection

Set ContentView.TabBadge to a string or binding. Assign null to clear it. TabBadgeColor replaces the system red background. A root page can update its badge even before the tab has been opened.

TabReselectedCommand replaces the default pop-to-root or scroll-to-top behavior for an already-selected tab.

The badge and reselection properties belong to ContentView; page chrome and toolbars covers the rest of the page-owned shell configuration.

iOS 26 additions

Search and Bubble adopt the separated trailing presentation on iOS 26. Their normal-tab fallbacks keep the same destinations and actions available on iOS 18.

Minimizes(...) allows the tab bar to minimize while scrolling. The running value is available through SkeleApplication.Current.TabBarMinimizeBehavior.

Accessory<TView>() hosts an app-level view above the tab bar; the view's IsVisible controls whether the slot is shown. SidebarFooter<TView>() fills the iPad sidebar footer. Both are ignored before iOS 26.