Search code examples
swiftuiswiftui-list

Swiftui - How to select both category and subcategory from the picker and ForEach list?


I would like to select both category and subcategory from the list Text to display category and subcategory names. For example, Food: Dinner

However the picker is only displaying category and not subCategory List.

Following is the code :

import SwiftUI

struct Category: Identifiable {
let id = UUID()
let title: String 
let SubCategory: [String]?
    }

struct SelectionList: View {

@State private var categoryList:String = ""

let categories = [
Category(title: "Food", SubCategory: ["Lunch", "Dinner"]),
Category(title: "Bills", SubCategory: ['Utility Bill", "Telephone Bill"])
]

var body: some View {

VStack {

Text (categoryList)
Form {
Picker ("Category", selection: ScategoryList) {
ForEach (dategories) { category in
    Text (category.title).tag(category.title)
      }
   }
   }
      }
   }
  }
}

Text to display both the category and subcategory names when they are selected from the list

Solution

  • First, let us indent the text and correct the type errors.

    import SwiftUI
    
    struct Category: Identifiable {
        let id = UUID()
        let title: String 
        let SubCategory: [String]?
    }
    
    struct SelectionList: View {
    
        @State private var categoryList: String = ""
    
        let categories = [
        Category(title: "Food", SubCategory: ["Lunch", "Dinner"]),
        Category(title: "Bills", SubCategory: ["Utility Bill", "Telephone Bill"])
        ]
    
        var body: some View {
    
            VStack {
    
                Text(categoryList)
                Form {
                    Picker ("Category", selection: ScategoryList) {
                        ForEach (dategories) { category in
                            Text (category.title).tag(category.title)
                        }
                    }
                 }
             }
         }
    }
    

    Second, the Category struct must conform to Hashable

    struct Category: Identifiable, Hashable{
        let id = UUID()
        let title: String 
        let SubCategory: [String]?
    }
    

    And now change the Picker to

    Menu("Category"){
        ForEach(categories, id: \.self){ category in
            Menu(category.title){
                ForEach(category.subCategory, id: \.self){ subCategory in
                    Button(subCategory){
                        categoryList = "\(subCategory) in \(category)."
                    }
                }
            }
        }
    }