.sharedBackgroundVisibility(.hidden) modifier directly to your ToolbarItem or ToolbarItemGroup. This hides the platform-default container styling without affecting the content inside.Why this happens
When building multiplatform apps for iOS and macOS, SwiftUI maps toolbar elements to platform-specific AppKit and UIKit primitives. In iOS, a .principal item in a navigation bar renders cleanly in the center of the bar without added ornaments. In contrast, macOS unified toolbars treat toolbar items as discrete controls and wrap them in standard chrome styling, such as translucent capsules or material backgrounds.
Starting with macOS 15 and iOS 18, Apple introduced shared toolbar backgrounds. By default, items added to navigation toolbars on macOS can automatically group inside a shared system background (often referred to as a glass or pill background). This visual treatment helps interactive controls stand out against window title bars.
However, when you place non-interactive views—such as a custom title using Text—inside a ToolbarItem(placement: .principal), macOS still applies this background container. Because SwiftUI does not differentiate between clickable toolbar controls and static text by placement alone, the toolbar item inherits the default background visibility.
How to fix it
1. Use the sharedBackgroundVisibility modifier
For apps targeting macOS 15 or newer (and iOS 18+), apply .sharedBackgroundVisibility(.hidden) directly to the ToolbarItem. This modifier tells the toolbar layout engine to suppress the default background pill for that specific item.
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationStack {
Text("Main Content View")
.toolbar {
ToolbarItem(placement: .principal) {
Text("Dashboard")
.font(.headline)
}
.sharedBackgroundVisibility(.hidden)
}
}
}
}
Make sure you apply .sharedBackgroundVisibility(.hidden) to the ToolbarItem itself, rather than to the inner Text view. The modifier is an extension on ToolbarContent, not on standard View.
If you have multiple items in a group that should not share a background, you can apply the modifier to the entire ToolbarItemGroup:
.toolbar {
ToolbarItemGroup(placement: .principal) {
Image(systemName: "waveform")
Text("Live Feed")
}
.sharedBackgroundVisibility(.hidden)
}
2. Use native navigation title APIs for static headers
If your goal is simply to display a custom title in the center of the toolbar or window header, placing a Text view inside .principal is often an antipattern on macOS. AppKit provides dedicated title handling that does not draw control backgrounds.
Replace the .principal item with .navigationTitle and customize the display mode when needed:
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationStack {
Text("Main Content View")
.navigationTitle("Dashboard")
#if os(iOS)
.navigationBarTitleDisplayMode(.inline)
#endif
}
}
}
This approach lets macOS render the title directly into the window chrome using standard macOS typography rules, avoiding toolbar item wrappers entirely.
3. Fallback for macOS 14 and earlier
If your deployment target includes macOS 14 (Sonoma) or earlier, .sharedBackgroundVisibility is not available. To strip default button chrome and backgrounds on older releases, adjust the toolbar style or apply a plain button style if your toolbar item contains interactive elements.
For interactive buttons that show unwanted background frames:
ToolbarItem(placement: .primaryAction) {
Button(action: refreshData) {
Label("Refresh", systemImage: "arrow.clockwise")
}
.buttonStyle(.plain)
}
For non-interactive content on macOS 14, avoid using .principal for text headers. Instead, set the navigation title natively or use .windowToolbarStyle to configure how controls integrate with the title bar:
@main
struct MultiplatformApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
.windowToolbarStyle(.unified(showsTitle: true))
}
}
How to prevent it
- Use semantic title modifiers: Prefer
.navigationTitle(_:)overToolbarItem(placement: .principal)when rendering plain text headers across iOS and macOS. - Scope toolbar modifiers to ToolbarContent: Always apply toolbar presentation modifiers (like
.sharedBackgroundVisibility) directly toToolbarItemorToolbarItemGroupinstances, not to the child views inside them. - Verify platform differences early: Check native macOS builds alongside iOS simulators during development, as macOS window toolbars enforce AppKit styling rules that differ from UIKit navigation bars.
- Apply plain button styles when necessary: If custom interactive icons inherit default toolbar borders or pill highlights on earlier macOS versions, assign
.buttonStyle(.plain)to the control.
FAQ
Does sharedBackgroundVisibility affect child view styling?
No. The modifier only hides or reveals the system-provided container chrome around the toolbar item. Any background colors, borders, or fills you explicitly apply to the view inside the ToolbarItem remain visible.
Can I use sharedBackgroundVisibility on individual views inside a ToolbarItemGroup?
No, the modifier attaches to ToolbarContent types such as ToolbarItem or ToolbarItemGroup. If you need different background settings for adjacent controls, declare them as separate ToolbarItem declarations rather than grouping them together.
Why does .principal placement look different on iOS and macOS?
On iOS, .principal maps to the center title position of a UINavigationBar. On macOS, it maps to the center region of an AppKit NSToolbar, where items default to standard toolbar control containers and tracking areas designed for mouse and trackpad interaction.
Parts of this guide are adapted from content licensed under CC BY-SA 4.0; this article is shared under the same license.
