Reputation: 37
This View
is drawing a grid based on a number of rows and columns. Say you have 2 rows and 2 colums you and up with 4 cells. Each cell has an .onTapGesture
which I like to use to change the cell color when clicked on.
I learned that I need to use a @State var
to keep track of changes (colors in this case) so redrawing will be automatic. But as soon as I pass the @State var
to the method for returning the new color, the onTapGesture
is not called at all. Why is that?
This is the View:
struct EditGridView: View {
@ObservedObject var playViewModel: PlayViewModel
@State var cellColors: [Color]
var body: some View {
VStack {
ForEach(0..<playViewModel.playViewState.currentInstrumentsSet.rows, id: \.self) { row in
HStack {
ForEach(0..<playViewModel.playViewState.currentInstrumentsSet.columns, id: \.self) { column in
ZStack {
RoundedRectangle(cornerRadius: 7.0)
.fill(
playViewModel.partColor(
row: row,
column: column,
cellColors: cellColors
)
)
.overlay(RoundedRectangle(cornerRadius: 7.0).stroke(Color("GridBorderColor")))
.cornerRadius(7.0)
}
.onTapGesture {
cellColors = playViewModel.tapOnCell(
index: InstrumentsSet.Track.Part.Index(row: row, column: column),
currentCellColors: cellColors
)
}
}
}
}
}.aspectRatio(1.77777, contentMode: .fit)
}
}
This is the method called, which does nothing yet but showing the current color:
public func partColor(row: Int, column: Int, cellColors: [Color]) -> Color {
let index: Int = row * setSettings.gridColumns + column
let color = cellColors[index]
print("color \(color) at index: \(index)")
return color
}
When I leave out the @State var cellColors
the function partColor
is called just fine. But I need to use this state var to redraw the new colors when changed? What trivial thing do I miss?
Upvotes: 1
Views: 236
Reputation: 2148
Try like this (hopefully the idea is clear):
struct EditGridView: View {
@ObservedObject var playViewModel: PlayViewModel
var body: some View {
VStack {
...
.fill(
playViewModel.partColor(row: row, column: column)
...
.onTapGesture {
playViewModel.tapOnCell(index: 0)
}
...
}
}
class PlayViewModel: ObservableObject {
@Published var cellColors: [Color] = [.red, .blue, .orange, .green]
func partColor(row: Int, column: Int) -> Color {
return cellColors[row + column]
}
func tapOnCell(index: Int) {
cellColors = [.green, .red, .blue, .orange]
}
}
Upvotes: 2