我使用 LazyGrid 制作了一个网格,我想根据数据模型中当前的选择状态来更改单个项目的背景颜色。
我尝试使用 onTapGesture() 它不会重新加载网格并更新背景颜色
class Day: Identifiable {
let id = UUID()
let value: Int
var isSelected: Bool
init(value: Int, isSelected: Bool) {
self.value = value
self.isSelected = isSelected
}
}
import SwiftUI
struct ContentView: View {
var days = [
Day(value: 1, isSelected: true),
Day(value: 2, isSelected: false),
Day(value: 3, isSelected: false),
Day(value: 4, isSelected: true)
]
let layout = [
GridItem(.fixed(40)),
GridItem(.fixed(40)),
GridItem(.fixed(40)),
GridItem(.fixed(40))
]
var body: some View {
ScrollView {
LazyVGrid(columns: layout) {
ForEach(days) { day in
Capsule()
.overlay(Text("\(day.value)").foregroundColor(.white))
.foregroundColor(day.isSelected ? .blue : .red)
.frame(height: 40)
.onTapGesture {
days[0].isSelected.toggle()
}
}
}
}
}
}
尝试这种方法,如前面提到的使用
struct Day
和 enumerated
在 ForEach
循环中,以及 @State private var days ...
,如示例代码所示:
struct Day: Identifiable { // <--- here
let id = UUID()
let value: Int
var isSelected: Bool
init(value: Int, isSelected: Bool) {
self.value = value
self.isSelected = isSelected
}
}
struct ContentView: View {
@State private var days = [ // <--- here
Day(value: 1, isSelected: true),
Day(value: 2, isSelected: false),
Day(value: 3, isSelected: false),
Day(value: 4, isSelected: true)
]
let layout = [
GridItem(.fixed(40)),
GridItem(.fixed(40)),
GridItem(.fixed(40)),
GridItem(.fixed(40))
]
var body: some View {
ScrollView {
LazyVGrid(columns: layout) {
// --- here
ForEach(Array(days.enumerated()), id: \.offset) { index, day in
Capsule()
.overlay(Text("\(day.value)").foregroundColor(.white))
.foregroundColor(day.isSelected ? .blue : .red)
.frame(height: 40)
.onTapGesture {
days[index].isSelected.toggle() // <--- here
}
}
}
}
}
}
或者:
struct ContentView: View {
@State private var days = [
Day(value: 1, isSelected: true),
Day(value: 2, isSelected: false),
Day(value: 3, isSelected: false),
Day(value: 4, isSelected: true)
]
let layout = [
GridItem(.fixed(40)),
GridItem(.fixed(40)),
GridItem(.fixed(40)),
GridItem(.fixed(40))
]
var body: some View {
ScrollView {
LazyVGrid(columns: layout) {
ForEach(days) { day in
Capsule()
.overlay(Text("\(day.value)").foregroundColor(.white))
.foregroundColor(day.isSelected ? .blue : .red)
.frame(height: 40)
.onTapGesture {
if let index = days.firstIndex(where: {$0.id == day.id}) {
days[index].isSelected.toggle() // <--- here
}
}
}
}
}
}
}