I’m brand new to Swift programming, and have pulled together a couple tutorials to try to make a simple Minesweeper iOS app. I want to have a menu at the bottom with an option to reset the board. I have a function in Game.swift that resets the board, and the main navigation is in MinesweeperApp.swift. I can’t figure out how to call the reset function from the navigation without getting an error.
My project structure is as such:
Minesweeper
├ View
| ├ CellView.swift
| └ BoardView.swift
├ Model
| ├ GameSettings.swift
| ├ Game.swift
| ├ Cell.swift
| └ Cell+Swift.swift
├ Shared
| ├ Assets.xcassets
| ├ MinesweeperApp.swift
| └ ContentView.swift
My Game.swift file:
class Game: ObservableObject {
// the game settings
@Published var settings: GameSettings
@Published var board: [[Cell]]
init(from settings: GameSettings) {
self.settings = settings
self.board = Game.GenerateBoard(from: settings)
}
... etc ...
func resetBoard() {
self.board = Game.GenerateBoard(from: settings)
}
My MinesweeperApp.swift file:
@main
struct MinesweeperApp: App {
var gameSettings = GameSettings() // the game settings
var body: some Scene {
WindowGroup {
NavigationView {
BoardView() // our content view
.environmentObject(Game(from: gameSettings)).padding()
.navigationTitle("Minesweeper")
.toolbar {
ToolbarItem(placement: .bottomBar) {
Button("Reset") {
Game.resetBoard()
print("Pressed")
}
}
}
}
}
}
}
When I take out the line Game.resetBoard() in MinesweeperApp, it works correctly and prints ‘pressed’. When I add that line in, the error I’m getting says
Instance member 'resetBoard' cannot be used on type 'Game'; did you mean to use a value of this type instead?
So, I’m trying to figure out how/where to call the reset function correctly.
The tutorials I used are
2
Answers
Right now, because you’re creating your instance of
Game
inside theenvironmentObject
call, you don’t have a reference stored at theApp
level to manipulate.The easiest fix would be this:
Then, you can call
resetBoard
on the instance ofGame
rather than trying to call it on the type (which is why you’re getting the error right now).This, of course, would depend on your sub views (like
Board
) using@EnvironmentObject var game : Game
instead of@EnvironmentObject var gameSettings : GameSettings
. And, you would access the settings in your subviews by doinggame.settings
Game = Class Game which cannot call non-static functions. You need to create Object before using ".resetBoard()" and I think it will be on top of your MinesweeperApp.