Home > Enterprise >  why data are passing back but SwiftUi not updating Text
why data are passing back but SwiftUi not updating Text

Time:09-23

I get to pass back data via closure, so new name is passed, but my UI is not updating. The new name of the user is printed when I go back to original view, but the text above the button is not getting that new value.

In my mind, updating startingUser should be enough to update the ContentView.

my ContentView:

@State private var startingUser: UserData?
        
var body: some View {
    
        VStack {
            Text(startingUser?.name ?? "no name")
            Text("Create start user")
                .onTapGesture {
                    startingUser = UserData(name: "Start User")
                }
        }
        .sheet(item: $startingUser) { userToSend in
            
            DetailView(user: userToSend) { newOnePassedFromWhatDoneInEDitView in
                startingUser = newOnePassedFromWhatDoneInEDitView
                print("✅ \(startingUser?.name)")
            }
        }

}

my EditView:

struct DetailView: View {
    
    @Environment(\.dismiss) var dismiss
    var user: UserData
    var callBackClosure: (UserData) -> Void

    @State private var name: String
    

    var body: some View {
        NavigationView {
            Form {
                TextField("your name", text: $name)
            }
            .navigationTitle("edit view")
            .toolbar {
                Button("dismiss") {
                    var newData = self.user
                    newData.name = name
                    newData.id = UUID()

                    callBackClosure(newData)
                    
                    dismiss()
                }
            }
        }
       
    
    }
    
    init(user: UserData,  callBackClosure: @escaping (UserData) -> Void ) {
        self.user = user
        self.callBackClosure = callBackClosure
        _name = State(initialValue: user.name)
    }
}

struct DetailView_Previews: PreviewProvider {
    static var previews: some View {
        DetailView(user: UserData.example) { _ in}
    }
}

my model

    struct UserData: Identifiable, Codable, Equatable {
        
        var id = UUID()
        var name: String
        
        static let example = UserData(name: "Luke")
        
        static func == (lhs: UserData, rhs: UserData) -> Bool {
            lhs.id == rhs.id
        }

}

update

using these changes solves the matter, but my question remains valid, cannot understand the right reason why old code not working, on other projects, where sheet and text depends on the same @state var it is working.

adding

@State private var show = false

adding

.onTapGesture {
      startingUser = UserData(name: "Start User")
      show = true
      }

changing

.sheet(isPresented: $show) {

                DetailView(user: startingUser ?? UserData.example) { newOnePassedFromWhatDoneInEDitView in
                    startingUser = newOnePassedFromWhatDoneInEDitView
                    print("✅ \(startingUser!.name)")
                }
            }
        

CodePudding user response:

The reason Text is not showing you the updated user name that you are passing in the closure is, your startingUser property will be set to nil when you dismiss the sheet because you have bind that property with sheet. Now after calling callBackClosure(newData) you are calling dismiss() to dismiss the sheet. To overcome this issue you can try something like this.

struct ContentView: View {
    @State private var startingUser: UserData?
    @State private var updatedUser: UserData?
            
    var body: some View {
        VStack {
            Text(updatedUser?.name ?? "no name")
            Text("Create start user")
                .onTapGesture {
                    startingUser = UserData(name: "Start User")
                }
        }
        .sheet(item: $startingUser) { userToSend in
            DetailView(user: userToSend) { newUser in
                updatedUser = newUser
                print("✅ \(updatedUser?.name ?? "no name")")
            }
        }
    }
}

I would suggest you to read the Apple documentation of sheet(item:onDismiss:content:) and check the example from the Discussion section to get more understanding.

  • Related