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

SwiftUI中如何检测主视图重新显示并获知此前被dismiss的子视图类型

实现方案

完全可以实现,核心是利用fullScreenCover的onDismiss回调+状态变量记录当前弹出的视图类型,具体实现如下:

1. 定义子视图标识枚举

先声明枚举区分不同的弹出视图,比用零散的Bool变量扩展性更强:

enum PresentedView: Identifiable {
    case view1
    case view2
    var id: Int { hashValue }
}

2. 主视图声明状态变量

// 控制fullScreenCover是否展示
@State private var presentedView: PresentedView?
// 存储当前正在展示的弹出视图,避免onDismiss时绑定值被自动置空拿不到标识
@State private var currentPresentedView: PresentedView?

3. 绑定按钮点击逻辑

点击按钮时同时给两个状态变量赋值:

// 按钮A点击逻辑
Button("打开子视图1") {
    currentPresentedView = .view1
    presentedView = .view1
}

// 按钮B点击逻辑
Button("打开子视图2") {
    currentPresentedView = .view2
    presentedView = .view2
}

4. 配置fullScreenCover的onDismiss回调

onDismiss的触发时机刚好是子视图完全关闭、原视图重新对用户可见的节点,你可以在这个回调里处理后续逻辑:

.fullScreenCover(item: $presentedView, onDismiss: {
    // 这里已经可以确定原视图重新可见
    guard let closedView = currentPresentedView else { return }
    // 根据被关闭的视图类型执行对应逻辑
    switch closedView {
    case .view1:
        print("刚关闭的是子视图1")
        // 执行子视图1关闭后的对应操作
    case .view2:
        print("刚关闭的是子视图2")
        // 执行子视图2关闭后的对应操作
    }
    // 可选:用完重置存储变量
    currentPresentedView = nil
}) { item in
    // 根据枚举返回对应的子视图
    switch item {
    case .view1:
        ChildView1()
    case .view2:
        ChildView2()
    }
}

补充说明

子视图内的关闭逻辑不需要修改,继续用@Environment(\.dismiss) var dismiss调用关闭即可,完全不影响上述逻辑的触发。如果你只有两个弹出视图不想定义枚举,用两个Bool变量分别控制两个视图的弹出、分别给两个fullScreenCover加独立的onDismiss回调也可以实现。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.08 05:18:03