I’ve produced a game using SwiftUI for the interface. It works as intended; i.e. play requires some reflection and then an input using buttons; only legal buttons are enabled so illegal input should be impossible. An animation is played when input is received and this is causing a problem. I discovered that if I play very quickly, tapping buttons without reflection, it seems I can overtake the animation and press buttons that should no longer be available effectively giving rise to an illegal move.
My question is, is there some way of locking out the interface as soon as input is received and only unlocking it after input has been processed and the interface update (which is almost instantaneous)? I’ve looked at NSLock and async/await but don’t see how they might be applied here.
These seem to be the relevant parts of my code with the animation commented out. When I apply the animation, I get the problem, so it seems to me that it is during the animation that I’m exposed to further button presses:
var action: (Int, Int) -> () {
if viewModel.nextGrid == nil {
return { r, c in
viewModel.selectNextGrid(Coordinate(r,c))
}
} else {
return { r, c in
viewModel.play(cell: Coordinate(r,c))
}
}
}
var body: some View {
VStack {
ForEach((0...2), id: \.self) { r in
HStack {
ForEach((0...2), id: \.self) { c in
let game = source(coord: Coordinate(r,c))
if !game.state.isEmpty() {
Text(game.state.rawValue)
} else {
Button {
// withAnimation {
// rotate += 180
action(r,c)
// }
} label: {
image
.resizable()
// .rotation3DEffect(.degrees(rotate), axis: (x:1,y:1,z:0))
}
}
}
}
}
}
}