'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 |