I’m creating a custom component: a list of cards.
Intended appearance:
This component accepts an array of generic type [T] and creates a card for each item in the array.
In this instance, I’m passing it an array of [PlantStage], which is an enum that represents various stages of gardening. Each stage has its own definition.
enum PlantStage: String, CaseIterable {
case seed = "Seed"
case germination = "Germination"
case seedling = "Seedling"
case bulb = "Bulb"
case leafyGrowth = "Leafy Growth"
case flowering = "Flowering"
case pollination = "Pollination"
case fruitFormation = "Fruit Formation"
case vegetableFormation = "Vegetable Formation"
case harvested = "Harvested"
var definition: String {
switch self {
case .seed: "A small object from which a new plant can grow."
case .germination: "The emergence of a tiny root and shoot."
case .seedling: "A young plant with its first set of leaves."
case .bulb: "An underground bulb from which a new plant can grow."
case .leafyGrowth: "The growth of leaves, stems, and roots establishing the plant."
case .flowering: "A stage where the plant produces flowers."
case .pollination: "A period of pollen transfer leading to plant fertilization."
case .fruitFormation: "The development of edible fruits."
case .vegetableFormation: "The development of edible greens."
case .harvested: "The act of gathering mature plants."
}
}
}
The problem is I can’t access definition. The cards end up looking like this:
My component code:
struct CardSelectionList<T>: View where T: RawRepresentable, T.RawValue == String {
let items: [T]
let newlySelectedPillText: String
let currentlyActivePillText: String
@Binding var selectedItem: T
@Binding var selectedIndex: Int
var body: some View {
ScrollView {
VStack(alignment: .leading, spacing: 10) {
ForEach(0..<items.count, id: .self) { i in
CardSelectable(
title: items[i].rawValue,
description: items[i].definition ?? nil,
currentlyActivePillText: currentlyActivePillText,
isNewlySelected: i == selectedIndex,
newlySelectedPillText: newlySelectedPillText
)
.onTapGesture {
selectedIndex = i
selectedItem = items[i]
}
}
}
}
}
}
#Preview {
CardSelectionList(
items: PlantStage.allCases,
newlySelectedPillText: "New Stage",
currentlyActivePillText: "Current Stage",
selectedItem: .constant(.seed),
selectedIndex: .constant(0)
)
}
I’m guessing because this component accepts an array of any type, not all types will have an associated definition. I tried addressing this by making card descriptions optional, but in this case it should have one.
I don’t understand why items[i].definition
doesn’t return the definition when items[i]
is of type PlantStage
and all plant stages have an associated definition.