iOS16+ SwiftUI:使用toolbarBackground时如何自定义导航标题样式
iOS 16+ 导航栏自定义:结合
.toolbarBackground与标题样式设置 问题根源
iOS 16+ 中,SwiftUI 的 .toolbarBackground 修饰符会优先覆盖 UIKit 层面的 UINavigationBarAppearance 配置,导致你之前通过 UIKit 自定义的标题样式被重置;同时直接向 .navigationTitle 传入自定义 Text 的方式已被废弃,因此会触发警告。另外,原代码中 configureWithTransparentBackground() 是导致滚动内容与导航栏重叠的核心原因。
解决方案:用 SwiftUI 原生 API 统一控制
放弃 UIKit 外观配置,改用 iOS 16+ 支持的 SwiftUI 原生导航栏修饰符,既能解决重叠问题,又能完全自定义标题样式。
1. 简化全局配置对象
保留全局色调管理,但移除 UIKit 相关的外观更新逻辑:
final class AppSettings: ObservableObject { @Published var tint: Color = .red }
2. 页面层级实现自定义导航栏
使用 NavigationStack(iOS 16+ 替代 NavigationView),结合 .toolbarBackground 和自定义 ToolbarItem 实现需求:
struct ContentView: View { @EnvironmentObject var settings: AppSettings var body: some View { NavigationStack { // 示例滚动内容 List(0..<20) { index in Text("列表项 \(index)") } // 设置标题显示模式(大标题/普通标题) .navigationBarTitleDisplayMode(.large) // 1. 设置导航栏背景:解决滚动重叠问题 .toolbarBackground(settings.tint.opacity(0.9), for: .navigationBar) .toolbarBackground(.visible, for: .navigationBar) // 强制滚动时背景可见 // 2. 自定义导航标题样式 .toolbar { ToolbarItem(placement: .principal) { // 大标题样式 Text("Today") .font(.system(.largeTitle, design: .rounded, weight: .black)) .foregroundColor(.white) // 可根据tint颜色调整对比色 // 如果是普通标题模式,替换为以下代码: // Text("Today") // .font(.system(.headline, design: .rounded, weight: .bold)) // .foregroundColor(settings.tint.opacity(0.9)) } } } } }
3. 支持动态字体(可选)
若需适配系统字体大小调整,使用动态字体 API:
Text("Today") .font(.preferredFont(forTextStyle: .largeTitle, design: .rounded).weight(.black))
关键说明
.toolbarBackground(.visible):强制导航栏在滚动过程中保持背景可见,彻底解决内容重叠问题。ToolbarItem(placement: .principal):这是 iOS 16+ 官方推荐的自定义导航标题的方式,完全规避.navigationTitle传入自定义Text的废弃警告。- 全局色调同步:通过
EnvironmentObject传递tint属性,确保所有页面的导航栏样式统一。
内容的提问来源于stack exchange,提问作者markb
相关产品推荐
相关产品推荐

