Reputation: 1452
I would like to pass a variable from a parent to a child view, but in this child view, use it in a text field but update this value only when a SAVE button is pressed.
I tried this:
ParentView
struct ParentView: View {
@State private var name: String = ""
var body: some View {
HStack {
Text("User name: \(name)")
Spacer()
NavigationLink(
destination: ChildView(name: name),
label: {
Text("Update name")
}
)
}
}
}
ChildView
struct ChildView: View {
@State private var name: String = ""
@Binding var passedName: String
var body: some View {
VStack {
Form {
TextField("Update name", text: $name)
Button(action: {
passedName = name
}, label: {
Text("SAVE")
})
}
}
}
init(name: String) {
self._passedName = .constant(name)
self.name = name
}
}
Since I don't want to update the variable directly, I tried to use a name
value and then only set the value of the binded passedName
when the OK button is tapped. But it doesn't work.
I don't know how to do what I want to.
Thank you for your help
Upvotes: 3
Views: 3794
Reputation: 49590
Your general approach is correct - have a state variable to represent a temporarily typed name, but a binding to represent the name "returned" to the parent.
Because the child modifies the data owned by the parent, it needs to accept a binding - not a plain String
:
struct ChildView: View {
@State private var name: String
@Binding var passedName: String
var body: some View {
VStack {
Form {
TextField("Update name", text: $name)
Button(action: {
passedName = name
}, label: {
Text("SAVE")
})
}
}
}
init(name: Binding<String>) {
self._passedName = name
self._name = State(initialValue: name.wrappedValue)
}
}
Then, pass in a binding from the parent:
ChildView(name: $name)
Upvotes: 7