iosswiftswiftuiswiftui-form

SwiftUI how to pass data to previous screen on dismiss


I want pass data on dismissing of presentViewController to previous screen. Here I would like to use block to pass data to previous screen as UIKitApp. But I'm not getting idea to pass data. What are the options we have to pass data to back?

struct ContentView: View {
    @State var showModel = false
    var body: some View {
        VStack {
            Button(action: {
                showModel.toggle()
            }, label: {
                Text("Show filters")
            }).sheet(isPresented: $showModel, content: {
                FilterView()
            })
        }
    }
}

struct FilterView: View {
    @Environment(\.presentationMode) var presentationMode

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

    var body: some View {
        
        VStack {
            Button(action: {
                // Pass data from here to ContentView
                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
}

Solution

  • You can use @Binding for that (or @StateObject, @ObservedObject, @Environmentobject with @ObservableObject using MVVM Design Pattern)

    The code below is an example using @Binding.

    Added/Edited Lines

    Text("\(filter.fromDate) and \(filter.toDate)") // to see the changed values
    
    @State var filter = Filter(fromDate: "", toDate: "") // in ContentView
    
    @Binding var filter: Filter // in FilterView
    
    FilterView(filter: $filter) // $ used for @Binding parameter
    

    Full Code

    struct ContentView: View {
        @State var showModel = false
        @State var filter = Filter(fromDate: "", toDate: "")
        
        var body: some View {
            VStack {
                Text("\(filter.fromDate) and \(filter.toDate)")
                Button(action: {
                    showModel.toggle()
                }, label: {
                    Text("Show filters")
                }).sheet(isPresented: $showModel, content: {
                    FilterView(filter: $filter)
                })
            }
        }
    }
    
    struct FilterView: View {
        @Environment(\.presentationMode) var presentationMode
    
        var onDismiss: ((_ model: Filter) -> Void)?
        @Binding var filter: Filter
    
        var body: some View {
            
            VStack {
                Button(action: {
                    // Pass data from here to ContentView
                    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
    }
    

    enter image description here

    enter image description here

    enter image description here