I often have need for multi-segment (hierarchical) pickers with dynamic data: in UIKit I achieve this by reloading a subsidiary component after the user picks a value from the higher level component, e.g. for Country then State.
I've been trying to achieve the same sort of effect with a SwiftUI Form containing multiple (two to start with) Pickers, but without success. The ForEach(0 ..< elements.count) pattern doesn't work with second and subsequent levels in the hierarchy because the number of elements in these levels changes depending on the chosen top level, e.g. countries have different numbers of states. The compiler throws a warning that the ForEach(0 ..< ) pattern can only be used with constants and to use ForEach(array, id: ): the results are unpredictable anyway with the 0..< approach, with subscript out of range crashes.
I can get correct display of second level choices based on the selected first level, but the Selection binding of the Picker doesn't work, i.e. no check marks and no display of selected element - only the available choices:
Picker(selection: $selection, label: Text("SubGroup")) {
ForEach(subGroups, id: \.id) { subGroup in
Text(subGroup.element)
}
}
With the ForEach(0 ..< pattern, the $selection refers to an Int, whereas using an Identifiable array the selection is (presumably) based on the id. But how to specify the binding for an id-based selection? Indeed, is this possible at all? I've seen a few posts on the Web querying this, with no answer.
UPDATE: OK, fixed it 🙂 I'd been using UUID as the id for each group and each subgroup within a group. When I use a unique integer id (or double, e.g. 1.1, 1.2 etc for two-level hierarchy) in an identifiable model, everything is fine. However, my code needs to provide the id of the initial selected (first?) row of the lower-level Picker when the higher level has changed.
Regards,
Michaela