使用Navigation与presentationBackground时视图重叠异常问题求助
问题分析与解决方案
异常表现

预期效果

复现步骤
- 打开Sheet
- 添加新条目
- 打开并关闭Sheet
- 点击返回按钮或“New item”按钮
问题原因
这是视图结构设计错误+SwiftUI渲染bug共同导致的:
- 在
navigationDestination中额外嵌套NavigationStack属于冗余设计——导航目的地视图会自动并入当前的导航栈,额外的嵌套会打乱SwiftUI的视图层级管理逻辑,导致视图销毁不彻底。 - 叠加
presentationBackground修饰符后,SwiftUI在处理Sheet关联视图的生命周期时出现异常,最终引发视图重叠问题。
修复方案
移除navigationDestination里的嵌套NavigationStack,让NewItemDetails直接作为导航目的地内容:
修改后的完整代码
import SwiftUI struct ContentView: View { @State var newItem: String? @State var sheetPresented = false var body: some View { NavigationStack { Button { sheetPresented = true } label: { Text("Open sheet") } .sheet(isPresented: $sheetPresented) { NavigationStack { Button { newItem = "New item" } label: { Text("Add new item") } // 移除冗余的NavigationStack,直接返回目标视图 .navigationDestination(item: $newItem) { item in NewItemDetails(item: item) } } } } } } struct NewItemDetails: View { @Environment(\.dismiss) var dismiss @State var openSheet = false let item: String init(item: String) { self.item = item } var body: some View { VStack(spacing: 20) { Button { dismiss() } label: { Text(item) } Button { openSheet = true } label: { Text("Open sheet") } } .sheet(isPresented: $openSheet) { Button { openSheet = false } label: { Text("After dismiss tap to 'New item' or Back") } .presentationBackground { Color.red } } } } #Preview { ContentView() }
补充说明
SwiftUI的导航栈与Sheet的组合逻辑对视图层级结构非常敏感,冗余的嵌套导航栈会干扰框架的视图生命周期管理。当再搭配presentationBackground这类自定义背景修饰符时,更容易触发渲染层面的异常。保持导航栈的扁平化结构是规避此类问题的核心原则。
内容的提问来源于stack exchange,提问作者miltenkot
相关产品推荐
相关产品推荐

