'SwiftUI - Generating Picker options from Multi-Level Struct (created from JSON)
I'm struggling to populate Picker on SwiftUI from Multi-Level Struct that is generated from a JSON data source. The struct has the following format
struct DataStruct : Codable {
let name: String
let group: [groupData]
}
struct groupData: Codable, Hashable {
let id, name : String
let point : [pointData]
}
struct pointData : Codable, Hashable {
let id : String
let name : String
let enumOptions: [String: String]
}
After loading the data from JSON, I get the following (simplified, real data has multiple Groups with multiple pointData groups, with each different Enum(erations).
DataStruct(name: "Top Level", group: [JSON.groupData(id: "1", name: "Group View", point: [JSON.pointData(id: "1", name: "Enumerated Point 1", enumOptions: ["1": "Enum2", "2": "Enum3", "0": "Enum1"])])])
Now I would like use the "Enumerated Point 1" data to create a picker for this data point. If this was 'hard-coded' this would be something like.
struct PickerView: View {
@State var pickerSelection : String = "2"
var body: some View {
Picker("Enumerations", selection: $pickerSelection) {
Text("Enum1").tag("0")
Text("Enum2").tag("1")
Text("Enum3").tag("2")
}
}
}
But I'm struggling to create Picker for 'Enumerated Point 1" as it is not an array but a dictionary? On the SwiftUI I have NavigationView on the top level with links to each "groups" of data (groupData), and then links to each "points" (pointData) that then have navigation link to the point.
The code snippet below illustrates how I drill in from top level to point level passing groupID and pointID as reference from one view to an other.
struct PickerView: View {
@State var pickerSelection : String = "2"
var groupID : String = "1" // Passed from Group Navigation Link
var pointID : String = "1" // Passed from Points Navigation Link
var body: some View {
VStack{
ForEach(dataStruct.group, id: \.self) { group in
if group.id == groupID {
ForEach(group.point, id: \.self) { point in
if point.id == pointID {
Text(point.name) // prints "Enumerated Point 1"
// Now here I would like to create the Picker from enumerations
// *** CODE HERE ***
}
}
}
}
}
}
}
Now I have tried to create Picker Enumerations using a further ForEach loop but without luck. Any ideas ?
Solution 1:[1]
The code below works. Each point element of the struct has array of pointEnumerations that are looped through using ForEach and then using Text("") the enumerations are created.
ForEach(group.point, id: \.self) { point in
if point.id == pointID {
VStack{
Text(point.name)
VStack {
Text("Selected option \(pickerSelection)")
Picker("Enum", selection: $pickerSelection) {
ForEach(0..<point.pointEnumerations.count, content : { index in
Text(point.pointEnumerations[index])
})
.pickerStyle(.wheel)
.frame(width: 230)
.padding(.leading, 35)
}
}
}
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Jukka |