I have an app where two different structs depend on a separate piece of data, and when I change that data, both structs need to know about the change. I think I could solve the problem with re-factoring, or with @EnvironmentObject, but I want to understand why this code does't work. In SceneDelegate.swift in an iOS project, set the contentView with let contentView = StateTestTopView() and then create a file with this code:
import SwiftUI
struct Person { @Binding var name: String }
struct Character { @Binding var name: String }
struct StateTestTopView: View {
@State private var name: String = "Bilbo"
var body: some View {
VStack {
StateTestPickerView(name: $name)
Spacer()
Text("Global name selection is \(name)").font(.title)
}
}
}
struct StateTestPickerView: View {
@Binding var name: String
@State private var person: Person
@State private var character: Character
init(name: Binding<String>) {
self._name = name
self._person = State(initialValue: Person(name: name))
self._character = State(initialValue: Character(name: name))
}
var body: some View {
VStack{
Picker(selection: $name,
label: Text(verbatim: "Selected name: \(name)")) {
ForEach(["Sam", "Gandalf", "Gollum"], id: \.self) { name in
Text(name)
}
}
Text("You picked \(name)")
ShowPersonAndCharacter(
person: self.$person, character: self.$character)
}
}
}
struct ShowPersonAndCharacter: View {
@Binding var person: Person
@Binding var character: Character
var body: some View {
Text("\(person.name) is great! \(character.name) is the same person!")
}
}
The problem is the ShowPersonAndCharacter has @Bindings to the Person and Character structs, but the bound structs don't update when the underlying data changes. I suspect the problem is in the Picker view initializer:
@Binding var name: String
@State private var person: Person
@State private var character: Character
init(name: Binding<String>) {
self._name = name
self._person = State(initialValue: Person(name: name))
self._character = State(initialValue: Character(name: name))
}
Here I think the Person and Character structs get created with a snapshot of the bound String and don't actually get the binding. I'm not sure how to fix this, or even if my diagnosis is remotely correct.
Any ideas?
Thanks for your time!