I have a simple app with a sidebar listing items and an edit view to edit the details of the selected item.
One of the parameters that can be changed in the edit view is the name of the item that is also shown in the sidebar.
Below is a simple app demonstrating the problem. It lits 4 people and you can change the name. When you change the name, the sidebar does not change until another is selected.
I would like the name in the sidebar to change as it is edited. If I added a text view in the edit view, then it would change as the TextField changes. Why does the item in the sidebar not change (or only change when selecting different item)?
class Person: NSObject, ObservableObject {
@Published public var name: String
init(name: String) {
self.name = name
}
}
class Database {
public var people: [Person]
init() {
people = [Person(name: "Susan"), Person(name: "John"),
Person(name: "Jack"), Person(name: "Mary")]
}
}
@main
struct BindingTestApp: App {
@State private var database = Database(
var body: some Scene {
WindowGroup {
ContentView(people: $database.people)
}
}
}
struct ContentView: View {
struct SidebarView: View {
@Binding var people: [Person]
@Binding var selectedPerson: Person?
var body: some View {
List(people, id: \.self, selection: $selectedPerson) { person in
Text(person.name)
}.listStyle(SidebarListStyle())
}
}
struct PersonView: View {
@ObservedObject public var person: Person
var body: some View {
TextField("Name", text: $person.name)
}
}
@Binding var people: [Person]
@State private var selectedPerson: Person?
var body: some View {
NavigationView {
SidebarView(people: $people, selectedPerson: $selectedPerson)
if let selectedPerson = selectedPerson {
PersonView(person: selectedPerson)
} else {
Text("Please select or create a person.")
}
}
}
}
struct ContentView_Previews: PreviewProvider {
@State static private var database = Database()
static var previews: some View {
ContentView(people: $database.people)
}
}