Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to refresh a view on dismiss of a sheet in SwiftUI

Tags:

swiftui

I want to get user input (using TextField) from one view and show it (the text which the user entered) in another view.

Here's a minimal, reproducible example

I created an ObservableObject named UserData

import Foundation
import  SwiftUI
import Combine

class UserData: ObservableObject {
    @Published var name: String = ""
}

Then I created a view named Edit with a TextField where user can enter a text

import SwiftUI

struct Edit: View {

    @ObservedObject var userData = UserData()

    var body: some View {
        VStack {
            TextField("Enter Name", text: $userData.name)
        }
    }
}

And here's the ContentView, the root view where I want to show the text which the user entered (initially, the text is empty).

import SwiftUI

struct ContentView: View {

    @State var isPresented = false
    @ObservedObject var userData = UserData()

    var body: some View {
        VStack {
            Text(self.userData.name)
                .font(.largeTitle)

            Button(action: { self.isPresented.toggle() }) {
                    Text("Click me to Edit")
            }
            .sheet(isPresented: $isPresented) {
                Edit()
            }
        }
    }
}

When we click the button in the ContentView, a sheet is presented with Edit view

When I click that button, a sheet with Edit view shows up ✅.
Then I can enter a text using the TextField ✅.
But when I dismiss the sheet by dragging down, the Text in the ContentView is still empty 🙁.

As I know, $userData.name updates when ever I enter something in the TextField.

But a Text in another view with a binding self.userData.name is not going to reflect the updated value 😫.


Is there any way to update the Text when we dismiss the sheet or is there any other way to do this?

Please help me.

Thanks for reading my question 😊

like image 580
umayanga Avatar asked Sep 05 '19 15:09

umayanga


1 Answers

Your Edit view and ContentView are each holding separate UserData objects. They don't share references to a single object, so editing one of them isn't updating the other.

First update your Edit view so it doesn't initialize its own UserData object:

@ObservedObject var userData: UserData

Then, in your ContentView, pass a reference to your single canonical UserData object into the Edit view:

.sheet(isPresented: $isPresented) {
    Edit(userData: self.userData)
}
like image 115
Clarko Avatar answered Oct 20 '22 18:10

Clarko