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

SwiftUI中fullScreenCover关闭后如何执行后续视图跳转逻辑?

SwiftUI中dismiss全屏覆盖视图后执行后续逻辑的正确方式

在SwiftUI里使用fullScreenCover展示全屏弹窗时,若调用dismiss()后立即触发新视图的展示(比如通过通知),会抛出[Presentation] Attempt to present xxx from yyy which is already presenting zzz错误。这是因为dismiss()是异步操作,弹窗还未完全关闭就发起新的present请求,导致冲突。

UIKit的dismiss方法支持通过completion回调在弹窗关闭后执行逻辑,SwiftUI中可以通过以下两种原生方式实现相同效果,避免使用不可靠的延迟方案:

方法一:利用视图的onDisappear回调

将后续逻辑放到弹窗视图的onDisappear中,确保视图真正消失后再执行操作。如果需要区分是按钮触发的关闭还是其他原因(比如系统返回),可以添加标记变量:

struct FullScreenCoverView: View {
    @Environment(\.dismiss) var dismiss
    @State private var isButtonTriggeredDismiss = false
    
    var body: some View {
        Button("This is a test") {
            isButtonTriggeredDismiss = true
            dismiss()
        }
        .onDisappear {
            // 仅在按钮触发关闭时执行逻辑
            if isButtonTriggeredDismiss {
                NotificationCenter.default.post(name: NSNotification.showNewScreen, object: nil)
            }
        }
    }
}

方法二:监听弹窗的展示状态变化

通过@Environment(\.presentationMode)监听弹窗的展示状态,当状态变为未展示时执行后续逻辑:

struct FullScreenCoverView: View {
    @Environment(\.dismiss) var dismiss
    @Environment(\.presentationMode) var presentationMode
    
    var body: some View {
        Button("This is a test") {
            dismiss()
        }
        .onChange(of: presentationMode.wrappedValue.isPresented) { isPresented in
            if !isPresented {
                NotificationCenter.default.post(name: NSNotification.showNewScreen, object: nil)
            }
        }
    }
}

这两种方法都能确保在弹窗完全关闭后再发起新的视图展示请求,不会出现冲突报错,比固定延迟的方案更可靠。

内容的提问来源于stack exchange,提问作者Buyin Brian

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 02:51:56