PAYATHON 2026

NavigationView 中 List 设置背景色后 Large Title 消失,如何解决?

排障赵师傅

结论

可以保留 List 和导航栏背景色。先显式设置 .navigationBarTitleDisplayMode(.large)。如果标题只在背景完全不透明时消失,再尝试降低导航栏背景的不透明度,或把颜色移到内容背景层。

对于 iOS 16 及以上的单列导航,建议同时将 NavigationView 换成 NavigationStack。这是 Apple 推荐的迁移方向,不过,仅更换容器未必能解决背景遮挡问题。Apple 导航迁移文档

为什么换成 List 后表现不同?

List 是可滚动容器,会与导航栏联动:列表位于顶部时显示 Large Title,向上滚动后标题收起。普通 ZStack 没有这种滚动行为,因此不能用同样的布局预期来判断两者的表现。

导航栏背景也受滚动状态影响:

  • .toolbarBackground(Color.pink, for: .navigationBar) 设置背景样式。
  • .toolbarBackground(.visible, for: .navigationBar) 让背景持续显示。

第二个修饰符只控制背景是否可见,不负责展开 Large Title。Apple API 文档

Color.pink.opacity(1) 完全不透明。在采用 Liquid Glass 外观的系统上,自定义导航背景可能干扰系统背景和滚动边缘效果。Apple 对此有明确提醒。不过,题目没有提供运行系统和 SDK 版本,因此无法确定具体的内部原因或受影响版本。Apple 外观适配说明

先明确标题模式,再排查不透明背景

在 iOS 16 及以上系统中,可以使用 NavigationStack,显式设置 Large Title,再将背景不透明度降到 0.7,排查是否存在背景遮挡:

import SwiftUI

struct ContentView: View {
    var body: some View {
        NavigationStack {
            List {
                Text("World")
            }
            .navigationTitle("Hello")
            .navigationBarTitleDisplayMode(.large)
            .toolbarBackground(
                Color.pink.opacity(0.7),
                for: .navigationBar
            )
            .toolbarBackground(.visible, for: .navigationBar)
        }
    }
}

.large 指定导航栏展开时使用大标题样式,滚动时标题仍会收起。标题显示模式文档

0.7 只是示例值,修复并不要求使用这个固定参数。如果降低不透明度后标题恢复,改回 1 又消失,应优先排查背景叠加,暂缓调整标题文字或字号。降低不透明度会改变最终显示的颜色,需要在目标系统上确认效果。

如果现有页面暂时保留 NavigationView,也可以先应用相同的标题模式和背景调整。

需要不透明底色时,把颜色放到内容背景层

如果设计要求使用不透明的粉色,可以移除导航栏上的自定义颜色,在 List 后面绘制背景,让颜色延伸到顶部安全区域。Apple 的工具栏设计指南也建议通过内容层影响工具栏外观。工具栏设计指南

以下写法会为整个页面背景着色:

import SwiftUI

struct ContentView: View {
    var body: some View {
        NavigationStack {
            List {
                Text("World")
            }
            .scrollContentBackground(.hidden)
            .background {
                Color.pink
                    .ignoresSafeArea()
            }
            .navigationTitle("Hello")
            .navigationBarTitleDisplayMode(.large)
            .toolbarBackground(.hidden, for: .navigationBar)
        }
    }
}

.scrollContentBackground(.hidden) 隐藏 List 的系统背景,让后面的粉色显示出来,但会保留列表行的背景。滚动内容背景文档

这种方案能保留导航区域背后的粉色视觉效果。粉色来自内容背景,导航栏自身的背景已隐藏。系统仍可能叠加滚动边缘效果,因此它与固定纯色导航栏的呈现效果并不完全相同。

注意事项

  • 先把列表滚回顶部再检查。滚动后 Large Title 收起属于正常行为。
  • 如果必须兼容 iOS 15,需要单独处理旧系统外观。toolbarBackground 从 iOS 16 起可用,不能直接用在旧系统分支中。
  • 在模拟器或真机上检查列表位于顶部和滚动后的状态。仅凭 Preview,无法确定问题是否只发生在预览环境。
  • 如果仍然异常,记录运行系统、构建 SDK,以及移除背景修饰符后的表现,再判断是否属于特定环境的渲染问题。

备注:内容仅供参考。