Я делаю простое приложение для тральщика. Внизу у меня есть панель инструментов с кнопкой для переключения, находится ли игра в «режиме флажков». У меня есть два возможных изображения для самой кнопки: одно, когда режим пометки включен, а другое, когда это не так, и я хотел бы, чтобы он переключался между ними при нажатии.

По сути, я хочу сделать переключатель с пользовательскими изображениями для включения/выключения.

Однако приведенный ниже код не обновляет изображение, и я не могу понять, почему.

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, и оно начало работать.

0
llllbbbbllll 19 Янв 2022 в 03:43
1
Этого кода недостаточно для диагностики проблемы. Можете ли вы включить game и как он хранится в представлении? Нам нужен минимально воспроизводимый пример, чтобы действительно дать хороший ответ.
 – 
jnpdx
19 Янв 2022 в 03:47
Конечно, спасибо за отзыв — я добавил свой файл для Game.swift. Я пытался вырезать все, что казалось неуместным, но дайте мне знать, если какой-либо информации все еще не хватает.
 – 
llllbbbbllll
19 Янв 2022 в 03:53
1
Это полезно, но мы еще не достигли минимально воспроизводимого примера. Можете ли вы включить что-то, что мы можем просто скопировать и вставить в Xcode и запустить?
 – 
jnpdx
19 Янв 2022 в 03:55
Вместо того, чтобы редактировать свой вопрос, чтобы включить решение, если вы считаете, что это полезно для других пользователей, вы должны добавить его в качестве ответа. Однако в этом случае я думаю, что вопрос, вероятно, следует просто удалить, поскольку ваше решение, вероятно, не будет применяться к другим ситуациям.
 – 
jnpdx
19 Янв 2022 в 05:23
Является ли game @ObservedObject ?
 – 
xTwisteDx
19 Янв 2022 в 05:44

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.

enter image description here

0
Guillermo Jiménez 19 Янв 2022 в 04:23

Самый простой способ справиться с этим — использовать переменную @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. 
                }         
     }
}
0
xTwisteDx 19 Янв 2022 в 05:33
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()
        }
    }
}
0
AdR 19 Янв 2022 в 14:34