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
相关产品推荐
相关产品推荐

