Я делаю простое приложение для тральщика. Внизу у меня есть панель инструментов с кнопкой для переключения, находится ли игра в «режиме флажков». У меня есть два возможных изображения для самой кнопки: одно, когда режим пометки включен, а другое, когда это не так, и я хотел бы, чтобы он переключался между ними при нажатии.
По сути, я хочу сделать переключатель с пользовательскими изображениями для включения/выключения.
Однако приведенный ниже код не обновляет изображение, и я не могу понять, почему.
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()
}
}
}
И мой файл Game.swift (сокращенный до необходимого)
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
}
Режим флага корректно переключается кнопкой. То есть, когда я нажимаю на него, чтобы он правильно помечал ячейки при нажатии. Поэтому я думаю, что проблема в представлении, а не в самой игре.
ИЗМЕНИТЬ (Решение):
У меня был этот код в моем основном файле MinesweeperApp.swift. Я поместил код панели инструментов в другое представление, которое вызывал MinesweeperApp, и оно начало работать.
3 ответа
Пара ошибок у вас есть:
В viewModel вы можете просто:
func toggleFlagMode() {
self.isFlagMode.toggle()
}
В представлении:
.environmentObject(game)
.padding()
.toolbar {
ToolbarItemGroup(placement: .bottomBar) {
Button(action: game.toggleFlagMode) {
Image(systemName: game.isFlagMode ? "square.and.arrow.up" : "pencil")
.resizable()
.aspectRatio(contentMode: .fit)
.foregroundColor(.red)
}
Button("Reset") {
game.resetBoard()
}
}
}
Если вы используете импортированные изображения (из Assets), не забудьте удалить systemName.
Самый простой способ справиться с этим — использовать переменную @State. Другими словами, это переменная, которая обновляет представление при изменении состояния. Например.
@State var isFlaggingModeEnabled = false
var body: some View {
Button(action: { isFlaggingModeEnabled.toggle() },
label: {
switch isFlaggingModeEnabled {
case true:
// Your image for when enabled.
default:
// Your image for when disabled.
}
}
}
GameView() // the content view
.environmentObject(game)
.padding()
.toolbar {
ToolbarItemGroup(placement: .bottomBar) {
Button(action: {
game.toggleFlagMode()
}) {
Image(game.isFlagMode ? "poire" : "pomme")
.resizable()
.aspectRatio(contentMode: .fit)
}
Button("Reset") {
game.resetBoard()
}
}
}
Похожие вопросы
Новые вопросы
ios
iOS - мобильная операционная система, работающая на Apple iPhone, iPod touch и iPad. Используйте этот тег [ios] для вопросов, связанных с программированием на платформе iOS. Используйте связанные теги [target-c] и [swift] для проблем, характерных для этих языков программирования.
game
и как он хранится в представлении? Нам нужен минимально воспроизводимый пример, чтобы действительно дать хороший ответ.game
@ObservedObject
?