I’m making a simple minesweeper app. At the bottom I have a toolbar with a button to toggle whether the game is in "flagging mode". I have two possible images for the button itself- one for when flagging mode is enabled and another for when it isn’t- and I’d like it to switch between the two when it’s clicked.
Essentially, I want to make a toggle with custom images for on/off.
However, the code I have below isn’t updating the image and I can’t figure out why.
GameView() // the content view
.environmentObject(game)
.padding()
.toolbar {
ToolbarItemGroup(placement: .bottomBar) {
Button(action: game.toggleFlagMode) {
if game.isFlagMode {
Image("flag toggle on")
.resizable()
.aspectRatio(contentMode: .fit)
}
else {
Image("flag toggle off")
.resizable()
.aspectRatio(contentMode: .fit)
}
}
Button("Reset") {
game.resetBoard()
}
}
}
And my Game.swift file (shortened to what’s relevant)
import Foundation
class Game: ObservableObject {
@Published var isFlagMode: Bool
[ ... ]
init(from settings: GameSettings) {
self.isFlagMode = false
[ ... ]
}
// toggle whether the game is in mode to flag cells
func toggleFlagMode() {
self.isFlagMode = !self.isFlagMode
}
Flag mode is correctly being toggled by the button. That is- when I click it to enable it’s properly flagging cells when clicked. So I think the issue is with the View and not Game itself.
EDIT (Solution):
I had this code in my main MinesweeperApp.swift file. I placed the toolbar code into a different view that MinesweeperApp was calling and it started working.
3
Answers
A couple of mistake you have:
In the viewModel you could just:
In the view:
If you are using imported images(from Assets) remember to remove the systemName.
The simplest way to handle this is with an @State variable. In other words it’s a variable that updates the view when the state changes. For example.