'SwiftUI select multiple item in a lazyhgrid
With SwiftUI this is my current code:
import SwiftUI
enum Items: String, CaseIterable, Equatable {
case item1
case item2
case item3
case item4
case item5
case item6
}
struct GridPicker: View {
var rows: [GridItem] = Array(repeating: .init(.flexible()), count: 3)
@State var isPressed = false
var body: some View {
NavigationView {
ScrollView(.horizontal) {
LazyHGrid(rows: rows) {
ForEach(Items.allCases, id: \.self) { value in
Button(action: {
isPressed = true
}, label: {
Text(value.rawValue)
.tag(value)
.foregroundColor(isPressed ? .purple : .white)
})
.frame(width: 85, height: 85)
.background(isPressed ? Color.white : Color.purple)
.clipShape(RoundedRectangle(cornerRadius: 10, style: .continuous))
}
}
}
}
.navigationViewStyle(StackNavigationViewStyle())
}
}
struct GridPicker_Previews: PreviewProvider {
static var previews: some View {
GridPicker()
}
}
I am trying to make it so I get a result like in the picture below.
Right now I have an enum what cases. I am trying to make each case selectable and then get back what cases in the enum the user has pressed so I can save the results in Core Data. Please note that the attribute in core data that I am trying to save this to is an Array of Strings.
The current issue:
When I press on one of the list items all of the items change color (I only want the selected item to change color)
How do I get back what case in the enum the user pressed in an array of strings format?
Solution 1:[1]
Add a new @State array to hold the selected items.
enum Items: String, CaseIterable, Equatable {
case item1
case item2
case item3
case item4
case item5
case item6
}
struct GridPicker: View {
var rows: [GridItem] = Array(repeating: .init(.flexible()), count: 3)
@State var selectedItems: [Items] = []
var body: some View {
NavigationView {
ScrollView(.horizontal) {
LazyHGrid(rows: rows) {
ForEach(Items.allCases, id: \.self) { item in
GridColumn(item: item, items: $selectedItems)
}
}
}
}
.navigationViewStyle(StackNavigationViewStyle())
}
}
struct GridPicker_Previews: PreviewProvider {
static var previews: some View {
GridPicker()
}
}
struct GridColumn:View {
let item: Items
@Binding var items: [Items]
var body: some View {
Button(action: {
if items.contains(item) {
items.removeAll { $0 == item}
} else {
items.append(item)
}
}, label: {
Text(item.rawValue)
.tag(item)
.foregroundColor(items.contains(item) ? .purple : .white)
})
.frame(width: 85, height: 85)
.background(items.contains(item) ? Color.white : Color.purple)
.clipShape(RoundedRectangle(cornerRadius: 10, style: .continuous))
}
}
This is not an array of strings but an array of Items (enum). Use an array of String should you need string.
You do not need to use isPressed.
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 |

