hallux
hallux

Reputation: 83

How to iterate through a enum to create a custom picker?

I'm attempting to create a custom picker using square tiles in a LazyHGrid view. The hope is to be able to use my enum which I had created for a picker I was previously using. That being said, I am unable to get it to properly display as it keeps telling me that my ForEach does not conform to RandomAccessCollection. I've attempted to do my due diligence in searching both here and Google.


let activityLevel: ActivityLevelSelector

enum ActivityLevelSelector: Double, CaseIterable {
    case sedentary = 1.2
    case lightlyActive = 1.375
    case moderatelyActive = 1.55
    case veryActive = 1.725
    
    var description: String {
        switch self {
        case .sedentary:
            return "Sedentary"
        case .lightlyActive:
            return "Lightly Active"
        case .moderatelyActive:
            return "Moderately Active"
        case .veryActive:
            return "Very Active"
        }
    }
}
var body: some View {
  NavigationView {
    VStack {
     Text("Please select your activity level.")
       .font(.caption)
      LazyHGrid(rows: [GridItem(.fixed(2))], content: {
          ForEach(activityLevel.description, id: \.self) { levelSelection in // Error Here! See Below!
                        print(levelSelection)
                    }
                })
            }
        }
    }
}

Error Displayed on identified line above...

Generic struct 'ForEach' requires that 'String' conform to 'RandomAccessCollection'

Upvotes: 0

Views: 895

Answers (1)

jnpdx
jnpdx

Reputation: 52387

You're trying to use ForEach on a single ActivityLevelSelector item. For ForEach to work, it needs to be a collection of items (an Array, for example). This might be more what you're looking for:

struct ContentView: View {
    let activityLevels: [ActivityLevelSelector] = ActivityLevelSelector.allCases
    
    var body: some View {
        NavigationView {
            VStack {
                Text("Please select your activity level.")
                    .font(.caption)
                LazyHGrid(rows: [GridItem(.fixed(2))]) {
                    ForEach(activityLevels, id: \.self) { levelSelection in
                        Text(levelSelection.description)
                    }
                }
            }
        }
    }
}

If .allCases is indeed what you want, you could simplify even a bit more, getting rid of the let activityLevels and doing::

ForEach(ActivityLevelSelector.allCases, id: \.self) { levelSelection in

Note also that you can't just print inside the ForEach -- you need to return a View of some sort.

Upvotes: 1

Related Questions