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

SwiftUI使用@Environment(\.dismiss)结合NavigationView/NavigationStack时崩溃

SwiftUI Sheet切换崩溃原因及解决办法

崩溃原因

核心问题出在复用同一个.sheet(item:)绑定变量切换Sheet时的上下文冲突:
当你点击Sheet一中的按钮,直接把bottomSheetType从.one改成.two,SwiftUI会尝试在当前Sheet还没完全关闭的情况下,立刻弹出新的Sheet。而视图B中存在的@Environment(\.dismiss)会关联当前Sheet的Presentation上下文,加上NavigationView/NavigationStack的层级约束,系统检测到同一个父控制器正在present一个视图控制器,又要present另一个,直接触发层级冲突崩溃。

解决办法

办法1:先关闭当前Sheet,再打开新Sheet

手动调用dismiss()释放当前上下文,再异步触发新Sheet的弹出,确保操作顺序正确:

case .one:
    Button("This is sheet one, click to open sheet two") {
        dismiss()
        DispatchQueue.main.async {
            self.bottomSheetType = .two
        }
    }

办法2:用独立绑定实现嵌套Sheet

为每个Sheet单独设置状态变量,让每个Sheet的弹出上下文完全独立,彻底避免冲突:

struct B: View {
    @Environment(\.dismiss) var dismiss
    
    @State private var showSheetOne = false
    @State private var showSheetTwo = false
    
    var body: some View {
        VStack(spacing: 0) {
            Button(action: {
                showSheetOne = true
            }, label: {
                Text("Click to open sheet A")
            })
        }
        .sheet(isPresented: $showSheetOne) {
            Button("This is sheet one, click to open sheet two") {
                showSheetTwo = true
            }
            .sheet(isPresented: $showSheetTwo) {
                Text("This is sheet two")
            }
        }
    }
}

办法3:复用枚举但通过回调确保顺序

如果要保留BottomSheetType枚举的用法,可以借助临时变量和异步操作,确保当前Sheet关闭后再打开新的:

.sheet(item: $bottomSheetType) { bottomSheetType in
    switch bottomSheetType{
    case .one:
        Button("This is sheet one, click to open sheet two") {
            let targetSheet = BottomSheetType.two
            dismiss()
            DispatchQueue.main.async {
                self.bottomSheetType = targetSheet
            }
        }
    case .two:
        Text("This is sheet two")
    }
}

内容的提问来源于stack exchange,提问作者Karan Peshwani

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 14:20:13