I'm really struggling to understand how the List(selection:) causes an update to the selection binding.
I am unpicking the Apple sample code at https://developer.apple.com/documentation/swiftui/building_a_great_mac_app_with_swiftui
The project is Session2/Part2-End/GardenApp.xcodeproj
There is a sidebar on the left, and the main detail view on the right. The ContentView looks like this:
struct ContentView: View {
@EnvironmentObject var store: Store
@SceneStorage("selection") private var selectedGardenID: Garden.ID?
@AppStorage("defaultGarden") private var defaultGardenID: Garden.ID?
var body: some View {
NavigationView {
Sidebar(selection: selection)
GardenDetail(garden: selectedGarden)
}
}
private var selection: Binding<Garden.ID?> {
Binding(get: { selectedGardenID ?? defaultGardenID }, set: { selectedGardenID = $0 })
}
private var selectedGarden: Binding<Garden> {
$store[selection.wrappedValue]
}
}
and the Sidebar like this:
struct Sidebar: View {
@EnvironmentObject var store: Store
@SceneStorage("expansionState") var expansionState = ExpansionState()
@Binding var selection: Garden.ID?
var body: some View {
List(selection: $selection) {
DisclosureGroup(isExpanded: $expansionState[store.currentYear]) {
ForEach(store.gardens(in: store.currentYear)) { garden in
SidebarLabel(garden: garden)
.badge(garden.numberOfPlantsNeedingWater)
}
} label: {
Label("Current", systemImage: "chart.bar.doc.horizontal")
}
Section("History") {
GardenHistoryOutline(range: store.previousYears, expansionState: $expansionState)
}
}
.frame(minWidth: 250)
}
}
Now the SidebarLabel view does not have any reference to the selection binding; yet, when you click on one of the labels, the selection updates and the binding propagates up to the ContentView and therefore the GardenDetai view is updated with the new selection.
My question is: how does clicking on one of the sidebar items cause the selection binding to be updated since there is no reference to the selection binding? Does the ForEach have anything to do with it?
If so, how can I add 'ad hoc' items that do not participate in a ForEach like this? If not, what is going on?