Your question has demonstrated that the modifier .toolbarColorScheme does not work for Mac Catalyst when the deployment option “Optimize for Mac” is selected.
Likewise, it seems that the navigation title does not get replaced by a ToolbarItem with placement .principal when this deployment option is used.
So workarounds are needed. Addressing some of the issues:
Applying dark mode
The modifier .preferredColorScheme(.dark) does work for the whole view hierarchy. However, this probably doesn’t help in your case, because you only want to force the toolbar to use dark color scheme. If I understand correctly, you want the main content to use the color scheme currently in operation.
Setting the toolbar background
The code shown in the question is setting the toolbar background to black using the modifier .toolbarBackground. This approach is now discouraged by Apple, ref. their best practice guidelines for Toolbars:
Reduce the use of toolbar backgrounds and tinted controls. Any custom backgrounds and appearances you use might overlay or interfere with background effects that the system provides. Instead, use the content layer to inform the color and appearance of the toolbar
If you change the existing code to set a blue background, instead of black, you will see that it doesn’t work well on iPad (when running iPadOS 26). So in accordance with the guideline, I would suggest applying the background to the content instead.
The following technique can be used to fill the background of the top safe area inset only:
mainContent
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(alignment: .top) {
Color.blue
.ignoresSafeArea()
.frame(height: 0)
}
Showing the title
To show a custom title with Mac Catalyst, the following works:
- hide the default title by applying
.toolbar(removing: .title) - show the custom title as a
ToolbarItemwith placement.navigation - hide the “shared background” behind the item
- set the foreground style to white explicitly.
For iPad, no workarounds are needed. So you may need to consider using different implementations for iOS and Mac Catalyst. The post Conditionally include macOS-only code in a SwiftUI (Mac Catalyst) project? shows ways of doing this.
Putting it all together
Here is a small example that shows a title in white on a blue background. It works quite consistently on both iPad and Mac Catalyst:
struct ToolbarModifiers: ViewModifier {
func body(content: Content) -> some View {
#if targetEnvironment(macCatalyst)
content.toolbar(removing: .title)
#else
content.toolbarColorScheme(.dark, for: .navigationBar)
#endif
}
}
struct ContentView: View {
let loremIpsum = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
private var titlePlacement: ToolbarItemPlacement {
#if targetEnvironment(macCatalyst)
.navigation
#else
.principal
#endif
}
var body: some View {
NavigationStack {
ScrollView {
VStack(spacing: 20) {
ForEach(0..<10) { _ in
Text(loremIpsum)
.font(.title3)
}
}
.padding()
}
.navigationTitle("Some Page")
.navigationBarTitleDisplayMode(.inline)
.modifier(ToolbarModifiers())
.toolbar {
ToolbarItem(placement: titlePlacement) {
Text("Custom Title")
.foregroundStyle(.white)
.font(.title3)
.fontWeight(.semibold)
}
.sharedBackgroundVisibility(.hidden)
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(alignment: .top) {
Color.blue
.ignoresSafeArea()
.frame(height: 0)
}
}
}
}
iPad:
[
Mac Catalyst:
