You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Navigation与presentationBackground时视图重叠异常问题求助

问题分析与解决方案

异常表现

异常效果

预期效果

预期效果

复现步骤

  • 打开Sheet
  • 添加新条目
  • 打开并关闭Sheet
  • 点击返回按钮或“New item”按钮

问题原因

这是视图结构设计错误+SwiftUI渲染bug共同导致的:

  1. 在navigationDestination中额外嵌套NavigationStack属于冗余设计——导航目的地视图会自动并入当前的导航栈,额外的嵌套会打乱SwiftUI的视图层级管理逻辑,导致视图销毁不彻底。
  2. 叠加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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 18:47:24