iOS 26 中 .presentationDetents 为什么会改变 sheet 层级?
数据小陈
结论
根据复现结果,这可能是 iOS 26.0 / 26.1 上 SwiftUI detent sheet 的显示层级异常:添加 .presentationDetents([.medium]) 后,根视图的背景或覆盖层会显示在 sheet 上方。iOS 18.5、18.6 及更早版本没有出现这一情况。不过,这份复现报告无法确认 Apple 是否已将其认定为系统回归,也无法确定具体原因。
.zIndex 无效并不意外。根视图和 .sheet 位于不同的呈现层级,调整同一视图层级中的顺序未必能改变 sheet 的系统呈现顺序。报告中的最小复现如下:
ZStack {
Color.red.opacity(0.3)
Button("Show") { show = true }
}
.sheet(isPresented: $show) {
Text("Sheet")
.presentationDetents([.medium])
}
可用的规避方式
如果需要避免根视图背景覆盖内容,同时不依赖系统 sheet 的拖拽和 detent 行为,可以先不用 .sheet,改为在同一个 ZStack 中自行显示底部面板。下面的示例将面板放在视图树中靠后的位置,使它显示在背景和按钮上方:
struct LoginScreen: View {
@State private var show = false
var body: some View {
ZStack(alignment: .bottom) {
Color.red.opacity(0.3)
.ignoresSafeArea()
Button("Show") {
show = true
}
if show {
Color.black.opacity(0.3)
.ignoresSafeArea()
.onTapGesture {
show = false
}
VStack {
Text("Sheet")
Button("Close") {
show = false
}
}
.frame(maxWidth: .infinity)
.frame(height: 360)
.background(.regularMaterial)
.clipShape(
UnevenRoundedRectangle(
topLeadingRadius: 20,
topTrailingRadius: 20
)
)
}
}
}
}
这是自定义面板,不会自动具备系统 sheet 的拖动手势、detent 切换和无障碍呈现等行为,需要根据产品需求自行补齐。如果这些系统能力不可替代,当前报告没有提供经过验证的原生 sheet 修复办法。可以先移除 .presentationDetents,确认显示层级是否恢复,再在目标系统版本上验证后续更新是否改变了表现。
注意事项
.presentationBackground 用于设置 sheet 自身的背景外观,未经验证时不应将它视为根视图覆盖问题的修复办法。调整 .zIndex 或改用 .overlay 也不能保证问题会消失,因为报告中这两种方式都没有改变结果。排查时,应使用相同的最小视图结构,分别在目标 iOS 版本和真机环境中验证。
备注:内容仅供参考。
