You need to enable JavaScript to run this app. SwiftUI dismiss返回上一页面时如何传递数据?有哪些实现方案?
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI dismiss返回上一页面时如何传递数据?有哪些实现方案?

SwiftUI 模态页面 dismiss 数据回传可选方案

方案1:闭包回传(和UIKit实现逻辑一致)

你现有的FilterView已经定义了onDismiss回调闭包,只需要在父视图ContentView创建FilterView时给闭包赋值,就能收到回传的Filter数据,修改后的代码如下:

struct ContentView: View {
    @State var showModel = false
    // 新增状态存储回传的筛选数据
    @State private var receivedFilter: Filter?

    var body: some View {
        VStack {
            // 可选:显示收到的筛选数据
            if let filter = receivedFilter {
                Text("选中区间:\(filter.fromDate) 至 \(filter.toDate)")
            }
            
            Button(action: {
                showModel.toggle()
            }, label: {
                Text("Show filters")
            }).sheet(isPresented: $showModel, content: {
                // 给FilterView传入onDismiss的实现逻辑
                FilterView(onDismiss: { filter in
                    receivedFilter = filter
                })
            })
        }
    }
}

// 原有FilterView代码不需要改动
struct FilterView: View {
    @Environment(\.presentationMode) var presentationMode

    var onDismiss: ((_ model: Filter) -> Void)?

    var body: some View {
        
        VStack {
            Button(action: {
                let filter = Filter(fromDate: "10/07/2021", toDate: "12/07/2021")
                onDismiss?(filter)
                presentationMode.wrappedValue.dismiss()
            }, label: {
                Text("Applay Filters")
            }).padding()
        }.padding()
    }
}

struct Filter {
    var fromDate: String
    var toDate: String
}

该方案适合页面层级浅、仅需要单次回调传值的场景,逻辑和UIKit的闭包回调完全一致。


方案2:@Binding 双向绑定传值

直接把父视图的状态变量通过绑定传到子视图,子视图修改绑定变量时父视图会自动同步更新,不需要手动触发回调,适合需要实时同步状态的场景:

// 父视图部分
.sheet(isPresented: $showModel, content: {
    FilterView(selectedFilter: $receivedFilter)
})

// 子视图FilterView部分
struct FilterView: View {
    @Environment(\.presentationMode) var presentationMode
    @Binding var selectedFilter: Filter?

    var body: some View {
        VStack {
            Button(action: {
                let filter = Filter(fromDate: "10/07/2021", toDate: "12/07/2021")
                selectedFilter = filter
                presentationMode.wrappedValue.dismiss()
            }, label: {
                Text("Applay Filters")
            }).padding()
        }.padding()
    }
}

方案3:EnvironmentObject 环境对象传值

适合多页面、多层级嵌套的视图共享数据的场景,不需要逐层传递闭包或者绑定,只需要把数据模型注入到父视图的环境中,所有子视图都可以直接访问和修改:

// 定义可观察的数据模型
class FilterViewModel: ObservableObject {
    @Published var selectedFilter: Filter?
}

// 父视图注入环境对象
struct ContentView: View {
    @State var showModel = false
    @StateObject private var vm = FilterViewModel()

    var body: some View {
        VStack {
            if let filter = vm.selectedFilter {
                Text("选中区间:\(filter.fromDate) 至 \(filter.toDate)")
            }
            Button(action: {
                showModel.toggle()
            }, label: {
                Text("Show filters")
            }).sheet(isPresented: $showModel, content: {
                FilterView()
                    .environmentObject(vm)
            })
        }
    }
}

// 子视图读取环境对象
struct FilterView: View {
    @Environment(\.presentationMode) var presentationMode
    @EnvironmentObject var vm: FilterViewModel

    var body: some View {
        VStack {
            Button(action: {
                vm.selectedFilter = Filter(fromDate: "10/07/2021", toDate: "12/07/2021")
                presentationMode.wrappedValue.dismiss()
            }, label: {
                Text("Applay Filters")
            }).padding()
        }.padding()
    }
}

方案4:监听sheet的onDismiss回调(iOS 15+支持)

如果不需要子视图主动触发回调,也可以在父视图监听sheet的消失事件,配合共享状态变量获取数据,适合页面关闭时统一处理逻辑的场景:

struct ContentView: View {
    @State var showModel = false
    @State private var tempFilter: Filter?
    @State private var receivedFilter: Filter?

    var body: some View {
        VStack {
            if let filter = receivedFilter {
                Text("选中区间:\(filter.fromDate) 至 \(filter.toDate)")
            }
            Button(action: {
                showModel.toggle()
            }, label: {
                Text("Show filters")
            })
            .sheet(isPresented: $showModel, onDismiss: {
                // sheet消失时同步数据
                receivedFilter = tempFilter
            }, content: {
                FilterView(selectedFilter: $tempFilter)
            })
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.12 15:00:06