Reputation: 27123
I am trying to create SwiftUI List based on enum strings. I am faced with this error:
Cannot invoke initializer for type 'List<_, _>' with an argument list of type '([HomeView.Data], @escaping (String) -> HomeMenuRow)'
I can't understand how to use id or how to iterate through enum to build a row.
Upvotes: 7
Views: 7936
Reputation: 4391
A ForEach
element needs a binding, so another option I tried is to use .constant
within the ForEach
. This does mean you might have to use item.wrappedValue
to access properties.
ForEach(.constant(Whatever.allCases)) { item in
Text(item.wrappedValue.rawValue)
}
Upvotes: 0
Reputation: 1385
You don't need Identifiable here. I've added selections as well, because why not:
enum Whatever: String, CaseIterable {
case one
case two
}
struct ContentView: View {
@Binding var selection: Whatever?
var body: some View {
VStack {
List (Whatever.allCases, id: \.rawValue, selection: $selection) { item in
Text(item.rawValue)
.tag(item)
}
}
}
}
Selection has to be optional (the error messages here are not overly helpful), but this is basically how you get a list that changes an enum value. You can also use this for type erasure to display sublists of different data types in a sidebar (eg books, magazines, videos): use an enum with associated data, group by enum case, and enjoy.
It is not necessary for id to be a static property; if your case is one(content: Book)
you can have a computed id property with a switch statement and case one(let book): return book.id
, and simply use an id: .id key path. (Unless elsewhere in Swift 5, the return keyword he remains mandatory).
Upvotes: 3
Reputation: 8091
try this:
enum Whatever : String, CaseIterable, Identifiable {
var id : String { UUID().uuidString }
case one = "one"
case two = "two"
}
struct ContentView: View {
var body: some View {
VStack {
List (Whatever.allCases) { value in
Text(value.rawValue)
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Upvotes: 17