apologies for the title, but I can't think of a more descriptive one. This is a bit long, apologies. I have my SOS game: https://github.com/johncwelch/SOS-Swift
Now, there's one thing making me a bit batty. So I have my grid:
Grid (horizontalSpacing: 0, verticalSpacing: 0){
ForEach(0..<boardSize, id: \.self) { row in
GridRow {
ForEach(0..<boardSize, id: \.self) { col in
GeometryReader { gridCellSize in
Button {
var theTuple = buttonClickStuff(for: gridCellArr[myIndex].index, theTitle: gridCellArr[myIndex].title, myArray: gridCellArr)
gridCellArr[myIndex].title = theTuple.myTitle
buttonBlank = theTuple.myCommitButtonStatus
lastButtonClickedIndex = gridCellArr[myIndex].index
} label: {
Text(gridCellArr[myIndex].title)
.font(.system(size: 36, weight: .heavy, design: .serif))
.frame(width: gridCellSize.frame(in: .global).width,height: gridCellSize.frame(in: .global).height, alignment: .center)
}
.background(gridCellArr[myIndex].backCol)
.border(Color.black)
.onAppear(perform: {
gridCellArr[myIndex].xCoord = col
gridCellArr[myIndex].yCoord = row
})
}
}
}
}
}
}
and here's the function buttonClickStuff():
func buttonClickStuff(for myIndex: Int, theTitle: String, myArray: [Cell]) -> (myColor: Color, myTitle:String, myCommitButtonStatus: Bool) {
var theCommitButtonStatus: Bool = false
var theCellTitle: String = ""
switch theTitle {
case "":
theCellTitle = "S"
theCommitButtonStatus = false
case "S":
theCellTitle = "O"
theCommitButtonStatus = false
case "O":
theCellTitle = ""
theCommitButtonStatus = true
default:
print("Something went wrong, try restarting the app")
}
let theColor: Color = Color.blue
let theReturnTuple = (myColor: theColor, myTitle: theCellTitle, myCommitButtonStatus: theCommitButtonStatus)
return theReturnTuple
}
and just for completeness sake, here's Cell that makes up the cell array:
@Observable
class Cell: Identifiable {
let id = UUID()
var title: String = ""
var buttonToggled: Bool = false
var index: Int = 0
var xCoord: Int = 0
var yCoord: Int = 0
var backCol: Color = .gray
}
so now I have a button that I need to be disabled or enabled based on the contents of a cell:
Button {
gridCellArr[lastButtonClickedIndex].backCol = .green
} label: {
Text("Commit Move")
}
.disabled(buttonBlank)
and buttonBlank is an @State var along with boardSize:
@State var boardSize: Int = 3
@State var buttonBlank: Bool = true
so the idea is, the board is built, all cells have a title of "" (blank) and Commit Move is disabled:
- the first time a button is clicked, its title should change to S and commit move is enabled
- second click, title changes to O, commit move is still enabled
- third click, title changes to "", commit move is disabled.
So a three-click rotation: "", "S", "O" what i'm actually getting is a four click rotation:
- first click, button doesn't visibly change, but it thinks the title is now "S" and the commit move button is enabled
- second click, Button does visibly change to "S", title is STILL "S", and the commit move button is enabled
- third click, button visibly changes to "O", title is "O" and the commit move button is enabled
- fourth click, button visibly changes to "", title is "" and the commit move button is disabled
that's the cycle, but it gets weirder.
suppose on button 0, i leave it at "S" or "O".
Then i click on button 1. I get:
- first click: button does visibly change to "S", title is "S", and the commit move button is enabled
- second click: button visibly changes to "O", title is "O" and the commit move button is enabled
- third click: BOTH buttons change to "", title for both is "" and the commit move button is disabled
if I keep clicking, it goes back to a four-click cycle
if I move the buttonBlank @state var underneath body, the "all buttons blank" problem goes away, it's a three click cycle as I expect, but buttonBlank never changes so the commit move button is always disabled.
what the heck? I am SO confused right now.